INTRO¶
Notebook for applying Data Assimilation on seasonal data (Lutetian reconstructions)¶
Author: N.J. de Winter (n.j.de.winter@vu.nl)
Assistant Professor Vrije Universiteit Amsterdam
References used in coding
Data assimiliation
- Steiger, N.J., Hakim, G.J., Steig, E.J., Battisti, D.S., Roe, G.H., 2014. Assimilation of Time-Averaged Pseudoproxies for Climate Reconstruction. Journal of Climate 27, 426–441. https://doi.org/10.1175/JCLI-D-12-00693.1
- Hakim, G.J., Emile-Geay, J., Steig, E.J., Noone, D., Anderson, D.M., Tardif, R., Steiger, N., Perkins, W.A., 2016. The last millennium climate reanalysis project: Framework and first results. Journal of Geophysical Research: Atmospheres 121, 6745–6764. https://doi.org/10.1002/2016JD024751
- King, J., Tierney, J., Osman, M., Judd, E.J., Anchukaitis, K.J., 2023. DASH: a MATLAB toolbox for paleoclimate data assimilation. Geoscientific Model Development 16, 5653–5683. https://doi.org/10.5194/gmd-16-5653-2023
- Judd, E.J., Tierney, J.E., Lunt, D.J., Montañez, I.P., Huber, B.T., Wing, S.L., Valdes, P.J., 2024. A 485-million-year history of Earth’s surface temperature. Science 385, eadk3705. https://doi.org/10.1126/science.adk3705
Data sources
- Van Horebeek, N., de Winter, N. J., Baatsen, M., Ziegler, M., Speijer, R. P., Vellekoop, J.: A European Monsoon-like climate in a Warmhouse World, Nature Communications, in review, 2025.
- Baatsen, M., von der Heydt, A.S., Huber, M., Kliphuis, M.A., Bijl, P.K., Sluijs, A., Dijkstra, H.A., 2020. The middle to late Eocene greenhouse climate modelled using the CESM 1.0.5. Climate of the Past 16, 2573–2597. https://doi.org/10.5194/cp-16-2573-2020
Calibration equations
- Harwood, A. J. P., Dennis, P. F., Marca, A. D., Pilling, G. M., and Millner, R. S.: The oxygen isotope composition of water masses within the North Sea, Estuarine, Coastal and Shelf Science, 78, 353–359, https://doi.org/10.1016/j.ecss.2007.12.010, 2008.
- Daëron, M. and Vermeesch, P.: Omnivariant generalized least squares regression: Theory, geochronological applications, and making the case for reconciled Δ47 calibrations, Chemical Geology, 121881, https://doi.org/10.1016/j.chemgeo.2023.121881, 2023.
- Grossman, E. L. and Ku, T.-L.: Oxygen and carbon isotope fractionation in biogenic aragonite: temperature effects, Chemical Geology: Isotope Geoscience section, 59, 59–74, 1986.
- Gonfiantini, R., Stichler, W., and Rozanski, K.: Standards and intercomparison materials distributed by the International Atomic Energy Agency for stable isotope measurements, 1995.
- Dettman, D. L., Reische, A. K., and Lohmann, K. C.: Controls on the stable isotope composition of seasonal growth bands in aragonitic fresh-water bivalves (Unionidae), Geochimica et Cosmochimica Acta, 63, 1049–1057, 1999.
Load packages¶
In [1]:
# Load packages
import numpy as np # The 'numpy' package is needed for matrix operations and calculations
import pandas as pd # The 'pandas' package helps us to import and manage data
import math as math # Math package for data cleaning
from scipy import stats # Import scipy.package for confidence intervals
from sklearn.preprocessing import StandardScaler # Import the package for standardizing data
import D47calib as D47c # Import the package for treating clumped isotope data by Daëron and Vermeesch (2023; https://github.com/mdaeron/D47calib)
import matplotlib.pyplot as plt # The 'matplotlib' package contains tools needed to plot our data and results
from matplotlib.patches import Rectangle # The 'Rectangle' function is used to add rectangles to our plots
import seaborn as sns # The 'seaborn' package is used to make our plots look nicer (e.g. enable heatmaps)
import warnings # The 'warnings' package is used to suppress warnings that might occur during the calculations
%matplotlib inline
In [2]:
# Load model SAT data as prior and show data structure
Lutetian_CESM_4PIC_SAT = pd.read_csv('Lutetian case/CESM_4PIC_SAT_Individual_values.csv') # Load the data from CESM model with 4x pre-industrial CO2 into Python and in the Jupyter environment.
print("CESM model 4PIC: ", Lutetian_CESM_4PIC_SAT.head())
Lutetian_CESM_2PIC_SAT = pd.read_csv('Lutetian case/CESM_2PIC_SAT_Individual_values.csv') # Load the data from CESM model with 2x pre-industrial CO2 into Python and in the Jupyter environment.
print("CESM model 2PIC: ", Lutetian_CESM_2PIC_SAT.head())
Lutetian_HadCM_new_1PIC_SAT = pd.read_csv('Lutetian case/HadCM_1PIC_SAT_new.csv') # Load the data from HadCM model with 1x pre-industrial CO2 into Python and in the Jupyter environment.
print("HadCM model 1PIC: ", Lutetian_HadCM_new_1PIC_SAT.head())
Lutetian_HadCM_new_2PIC_SAT = pd.read_csv('Lutetian case/HadCM_2PIC_SAT_new.csv') # Load the data from HadCM model with 2x pre-industrial CO2 into Python and in the Jupyter environment.
print("HadCM model 2PIC: ", Lutetian_HadCM_new_2PIC_SAT.head())
Lutetian_HadCM_new_1056ppm_SAT = pd.read_csv('Lutetian case/HadCM_1056ppm_SAT_new.csv') # Load the data from HadCM model with 1056ppm CO2 into Python and in the Jupyter environment.
print("HadCM model 1056ppm: ", Lutetian_HadCM_new_1056ppm_SAT.head())
Lutetian_HadCM_old_2PIC_SAT = pd.read_csv('Lutetian case/HadCM_2PIC_SAT_old.csv') # Load the data from HadCM model with 2x pre-industrial CO2 into Python and in the Jupyter environment.
print("HadCM model 2PIC (old): ", Lutetian_HadCM_old_2PIC_SAT.head())
Lutetian_HadCM_old_4PIC_SAT = pd.read_csv('Lutetian case/HadCM_4PIC_SAT_old.csv') # Load the data from HadCM model with 4x pre-industrial CO2 into Python and in the Jupyter environment.
print("HadCM model 4PIC (old): ", Lutetian_HadCM_old_4PIC_SAT.head())
CESM model 4PIC: Month Temperature 0 1 11.282648 1 1 21.823206 2 1 21.909296 3 1 22.503198 4 1 21.393762 CESM model 2PIC: Month Temperature 0 1 8.079706 1 1 18.723108 2 1 18.902612 3 1 19.552850 4 1 18.329370 HadCM model 1PIC: Month SAT 0 1 8.052789 1 1 5.543665 2 1 5.441797 3 1 11.657343 4 1 3.336206 HadCM model 2PIC: Month SAT 0 1 12.032495 1 1 10.032343 2 1 10.042474 3 1 15.231805 4 1 7.854364 HadCM model 1056ppm: Month SAT 0 1 14.752985 1 1 12.996912 2 1 13.127679 3 1 17.809625 4 1 11.005304 HadCM model 2PIC (old): Month SAT 0 1 16.109460 1 1 14.491327 2 1 14.220056 3 1 18.878229 4 1 10.043237 HadCM model 4PIC (old): Month SAT 0 1 16.109460 1 1 14.491327 2 1 14.220056 3 1 18.878229 4 1 10.043237
Load monthly SST model data¶
In [3]:
# Load model SST data as prior and show data structure
Lutetian_CESM_4PIC_SST = pd.read_csv('Lutetian case/CESM_4PIC_SST_Individual_values.csv') # Load the data from CESM model with 4x pre-industrial CO2 into Python and in the Jupyter environment.
print("CESM model 4PIC: ", Lutetian_CESM_4PIC_SST.head())
Lutetian_CESM_2PIC_SST = pd.read_csv('Lutetian case/CESM_2PIC_SST_Individual_values.csv') # Load the data from CESM model with 2x pre-industrial CO2 into Python and in the Jupyter environment.
print("CESM model 2PIC: ", Lutetian_CESM_2PIC_SST.head())
Lutetian_HadCM_new_1PIC_SST = pd.read_csv('Lutetian case/HadCM_1PIC_SST_new.csv') # Load the data from HadCM model with 1x pre-industrial CO2 into Python and in the Jupyter environment.
print("HadCM model 1PIC: ", Lutetian_HadCM_new_1PIC_SST.head())
Lutetian_HadCM_new_2PIC_SST = pd.read_csv('Lutetian case/HadCM_2PIC_SST_new.csv') # Load the data from HadCM model with 2x pre-industrial CO2 into Python and in the Jupyter environment.
print("HadCM model 2PIC: ", Lutetian_HadCM_new_2PIC_SST.head())
Lutetian_HadCM_new_1056ppm_SST = pd.read_csv('Lutetian case/HadCM_1056ppm_SST_new.csv') # Load the data from HadCM model with 1056ppm CO2 into Python and in the Jupyter environment.
print("HadCM model 1056ppm: ", Lutetian_HadCM_new_1056ppm_SST.head())
Lutetian_HadCM_old_2PIC_SST = pd.read_csv('Lutetian case/HadCM_2PIC_SST_old.csv') # Load the data from HadCM model with 2x pre-industrial CO2 into Python and in the Jupyter environment.
print("HadCM model 2PIC (old): ", Lutetian_HadCM_old_2PIC_SST.head())
Lutetian_HadCM_old_4PIC_SST = pd.read_csv('Lutetian case/HadCM_4PIC_SST_old.csv') # Load the data from HadCM model with 4x pre-industrial CO2 into Python and in the Jupyter environment.
print("HadCM model 4PIC (old): ", Lutetian_HadCM_old_4PIC_SST.head())
CESM model 4PIC: Month SST 0 1 25.653111 1 1 25.308791 2 1 24.928478 3 1 18.123590 4 1 18.129648 CESM model 2PIC: Month SST 0 1 22.904200 1 1 22.584154 2 1 22.211651 3 1 14.667439 4 1 14.675111 HadCM model 1PIC: Month SST 0 1 17.121233 1 1 17.339096 2 1 15.036237 3 1 17.758467 4 1 16.707846 HadCM model 2PIC: Month SST 0 1 19.588043 1 1 19.876625 2 1 17.857376 3 1 20.270193 4 1 19.358486 HadCM model 1056ppm: Month SST 0 1 21.546501 1 1 21.834936 2 1 19.857330 3 1 22.318356 4 1 21.426821 HadCM model 2PIC (old): Month SST 0 1 22.036110 1 1 21.993841 2 1 21.271461 3 1 21.397297 4 1 20.712231 HadCM model 4PIC (old): Month SST 0 1 22.036110 1 1 21.993841 2 1 21.271461 3 1 21.397297 4 1 20.712231
Load monthly SSS model data¶
In [4]:
# Load model SSS data as prior and show data structure
Lutetian_CESM_4PIC_SSS = pd.read_csv('Lutetian case/CESM_4PIC_SSS_Individual_values.csv') # Load the data from CESM model with 4x pre-industrial CO2 into Python and in the Jupyter environment.
print("CESM model 4PIC: ", Lutetian_CESM_4PIC_SSS.head())
Lutetian_CESM_2PIC_SSS = pd.read_csv('Lutetian case/CESM_2PIC_SSS_Individual_values.csv') # Load the data from CESM model with 2x pre-industrial CO2 into Python and in the Jupyter environment.
print("CESM model 2PIC: ", Lutetian_CESM_2PIC_SSS.head())
Lutetian_HadCM_new_1PIC_SSS = pd.read_csv('Lutetian case/HadCM_1PIC_SSS_new.csv') # Load the data from HadCM model with 1x pre-industrial CO2 into Python and in the Jupyter environment.
print("HadCM model 1PIC: ", Lutetian_HadCM_new_1PIC_SSS.head())
Lutetian_HadCM_new_2PIC_SSS = pd.read_csv('Lutetian case/HadCM_2PIC_SSS_new.csv') # Load the data from HadCM model with 2x pre-industrial CO2 into Python and in the Jupyter environment.
print("HadCM model 2PIC: ", Lutetian_HadCM_new_2PIC_SSS.head())
Lutetian_HadCM_new_1056ppm_SSS = pd.read_csv('Lutetian case/HadCM_1056ppm_SSS_new.csv') # Load the data from HadCM model with 1056ppm CO2 into Python and in the Jupyter environment.
print("HadCM model 1056ppm: ", Lutetian_HadCM_new_1056ppm_SSS.head())
Lutetian_HadCM_old_2PIC_SSS = pd.read_csv('Lutetian case/HadCM_2PIC_SSS_old.csv') # Load the data from HadCM model with 2x pre-industrial CO2 into Python and in the Jupyter environment.
print("HadCM model 2PIC (old): ", Lutetian_HadCM_old_2PIC_SSS.head())
Lutetian_HadCM_old_4PIC_SSS = pd.read_csv('Lutetian case/HadCM_4PIC_SSS_old.csv') # Load the data from HadCM model with 4x pre-industrial CO2 into Python and in the Jupyter environment.
print("HadCM model 4PIC (old): ", Lutetian_HadCM_old_4PIC_SSS.head())
CESM model 4PIC: Month SSS 0 1 35.445849 1 1 35.447266 2 1 35.370330 3 1 27.677744 4 1 27.647815 CESM model 2PIC: Month SSS 0 1 35.611739 1 1 35.605736 2 1 35.525519 3 1 28.101734 4 1 28.084953 HadCM model 1PIC: Month SSS 0 1 36.600336 1 1 36.589958 2 1 36.418869 3 1 36.613618 4 1 36.546343 HadCM model 2PIC: Month SSS 0 1 36.903056 1 1 36.886427 2 1 36.710143 3 1 36.917722 4 1 36.842750 HadCM model 1056ppm: Month SSS 0 1 37.131014 1 1 37.101769 2 1 36.907516 3 1 37.167668 4 1 37.071734 HadCM model 2PIC (old): Month SSS 0 1 43.906515 1 1 44.145954 2 1 44.298574 3 1 44.078606 4 1 44.195226 HadCM model 4PIC (old): Month SSS 0 1 43.906515 1 1 44.145954 2 1 44.298574 3 1 44.078606 4 1 44.195226
Load monthly precipitation model data¶
In [5]:
# Load model precipitation data as prior and show data structure
Lutetian_CESM_4PIC_prec = pd.read_csv('Lutetian case/CESM_4PIC_Precipitation_Individual_values.csv') # Load the data from CESM model with 4x pre-industrial CO2 into Python and in the Jupyter environment.
print("CESM model 4PIC: ", Lutetian_CESM_4PIC_prec.head())
Lutetian_CESM_2PIC_prec = pd.read_csv('Lutetian case/CESM_2PIC_Precipitation_Individual_values.csv') # Load the data from CESM model with 2x pre-industrial CO2 into Python and in the Jupyter environment.
print("CESM model 2PIC: ", Lutetian_CESM_2PIC_prec.head())
Lutetian_HadCM_new_1PIC_prec = pd.read_csv('Lutetian case/HadCM_1PIC_Precipitation_new.csv') # Load the data from HadCM model with 1x pre-industrial CO2 into Python and in the Jupyter environment.
print("HadCM model 1PIC: ", Lutetian_HadCM_new_1PIC_prec.head())
Lutetian_HadCM_new_2PIC_prec = pd.read_csv('Lutetian case/HadCM_2PIC_Precipitation_new.csv') # Load the data from HadCM model with 2x pre-industrial CO2 into Python and in the Jupyter environment.
print("HadCM model 2PIC: ", Lutetian_HadCM_new_2PIC_prec.head())
Lutetian_HadCM_new_1056ppm_prec = pd.read_csv('Lutetian case/HadCM_1056ppm_Precipitation_new.csv') # Load the data from HadCM model with 1056ppm CO2 into Python and in the Jupyter environment.
print("HadCM model 1056ppm: ", Lutetian_HadCM_new_1056ppm_prec.head())
Lutetian_HadCM_old_2PIC_prec = pd.read_csv('Lutetian case/HadCM_2PIC_Precipitation_old.csv') # Load the data from HadCM model with 2x pre-industrial CO2 into Python and in the Jupyter environment.
print("HadCM model 2PIC (old): ", Lutetian_HadCM_old_2PIC_prec.head())
Lutetian_HadCM_old_4PIC_prec = pd.read_csv('Lutetian case/HadCM_4PIC_Precipitation_old.csv') # Load the data from HadCM model with 4x pre-industrial CO2 into Python and in the Jupyter environment.
print("HadCM model 4PIC (old): ", Lutetian_HadCM_old_4PIC_prec.head())
CESM model 4PIC: Month Precipitation 0 1 3.528070 1 1 1.148649 2 1 2.255904 3 1 2.247083 4 1 2.146144 CESM model 2PIC: Month Precipitation 0 1 4.098786 1 1 1.263385 2 1 2.206109 3 1 2.211890 4 1 2.020240 HadCM model 1PIC: Month Precipitation 0 1 2.406142 1 1 1.957261 2 1 3.106018 3 1 2.795490 4 1 2.562401 HadCM model 2PIC: Month Precipitation 0 1 3.428225 1 1 2.581973 2 1 3.858653 3 1 3.660850 4 1 3.468367 HadCM model 1056ppm: Month Precipitation 0 1 4.779313 1 1 3.294503 2 1 4.737308 3 1 4.740917 4 1 4.566842 HadCM model 2PIC (old): Month Precipitation 0 1 5.331755 1 1 3.825469 2 1 5.138381 3 1 4.515986 4 1 4.612467 HadCM model 4PIC (old): Month Precipitation 0 1 5.331755 1 1 3.825469 2 1 5.138381 3 1 4.515986 4 1 4.612467
Combine climate data by modelname¶
For CESM with 4x preindustrial pCO2¶
In [6]:
# For CESM model with 4x pre-industrial CO2, combine the datasets of SAT, SST, SSS and prec into one dataset for further analysis
# Add a column to number the rows within each month consecutively
Lutetian_CESM_4PIC_SAT['Cell'] = Lutetian_CESM_4PIC_SAT.groupby('Month').cumcount() + 1
Lutetian_CESM_4PIC_SST['Cell'] = Lutetian_CESM_4PIC_SST.groupby('Month').cumcount() + 1
Lutetian_CESM_4PIC_SSS['Cell'] = Lutetian_CESM_4PIC_SSS.groupby('Month').cumcount() + 1
Lutetian_CESM_4PIC_prec['Cell'] = Lutetian_CESM_4PIC_prec.groupby('Month').cumcount() + 1
# Pivot the datasets to create separate columns for each month with 2-letter abbreviations
month_abbreviations = ['ja', 'fb', 'mr', 'ar', 'my', 'jn', 'jl', 'ag', 'sp', 'ot', 'nv', 'dc']
Lutetian_CESM_4PIC_SAT_wide = Lutetian_CESM_4PIC_SAT.pivot(index='Cell', columns='Month', values='Temperature')
Lutetian_CESM_4PIC_SAT_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_CESM_4PIC_SAT_wide.columns]
Lutetian_CESM_4PIC_SST_wide = Lutetian_CESM_4PIC_SST.pivot(index='Cell', columns='Month', values='SST')
Lutetian_CESM_4PIC_SST_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_CESM_4PIC_SST_wide.columns]
Lutetian_CESM_4PIC_SSS_wide = Lutetian_CESM_4PIC_SSS.pivot(index='Cell', columns='Month', values='SSS')
Lutetian_CESM_4PIC_SSS_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_CESM_4PIC_SSS_wide.columns]
Lutetian_CESM_4PIC_prec_wide = Lutetian_CESM_4PIC_prec.pivot(index='Cell', columns='Month', values='Precipitation')
Lutetian_CESM_4PIC_prec_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_CESM_4PIC_prec_wide.columns]
# Reset the index to make 'Cell' a column again
Lutetian_CESM_4PIC_SAT_wide.reset_index(inplace = True)
Lutetian_CESM_4PIC_SST_wide.reset_index(inplace = True)
Lutetian_CESM_4PIC_SSS_wide.reset_index(inplace = True)
Lutetian_CESM_4PIC_prec_wide.reset_index(inplace = True)
# Merge the datasets of SAT, SST, SSS and prec, force suffixes to be added to the column names
# Merge in two steps to circumvent different numbers of cells due to differing spatial resolution in air and ocean models
Lutetian_CESM_4PIC_model = pd.merge(
# Merge SAT and prec data
pd.merge(
Lutetian_CESM_4PIC_SAT_wide.rename(columns = {c: c+'_SAT' for c in Lutetian_CESM_4PIC_SAT_wide.columns if c != 'Cell'}),
Lutetian_CESM_4PIC_prec_wide.rename(columns = {c: c+'_precip' for c in Lutetian_CESM_4PIC_prec_wide.columns if c != 'Cell'}),
on = 'Cell',
how = 'outer'
),
# Merge SST and SSS data
pd.merge(
Lutetian_CESM_4PIC_SST_wide.rename(columns = {c: c+'_SST' for c in Lutetian_CESM_4PIC_SST_wide.columns if c != 'Cell'}),
Lutetian_CESM_4PIC_SSS_wide.rename(columns = {c: c+'_SSS' for c in Lutetian_CESM_4PIC_SSS_wide.columns if c != 'Cell'}),
on = 'Cell',
how = 'outer'
),
on = 'Cell',
how = 'outer'
)
# Display the combined dataset
print("CESM 4x pre-industrial CO2 combined dataset:")
print(Lutetian_CESM_4PIC_model.head())
CESM 4x pre-industrial CO2 combined dataset:
Cell ja_SAT fb_SAT mr_SAT ar_SAT my_SAT jn_SAT \
0 1 11.282648 12.089380 13.829187 16.709039 22.411493 27.940820
1 2 21.823206 22.185327 23.480707 25.735864 30.242242 35.107660
2 3 21.909296 22.198022 23.222040 25.234583 29.434015 34.056543
3 4 22.503198 22.530481 23.346246 25.152704 28.970605 33.480951
4 5 21.393762 21.576868 22.996118 25.669275 30.826440 36.038263
jl_SAT ag_SAT sp_SAT ... mr_SSS ar_SSS my_SSS \
0 30.968195 31.072290 26.694391 ... 35.461410 35.476315 35.502321
1 38.680688 39.036523 35.629755 ... 35.474837 35.491815 35.518168
2 38.089227 38.691492 35.554956 ... 35.391840 35.407201 35.434341
3 37.780298 38.492792 35.470605 ... 27.740462 27.669306 27.565980
4 40.872888 40.882013 36.701257 ... 27.695703 27.609018 27.476092
jn_SSS jl_SSS ag_SSS sp_SSS ot_SSS nv_SSS dc_SSS
0 35.524816 35.519439 35.469567 35.353144 35.262145 35.298730 35.386242
1 35.535836 35.529558 35.499538 35.409034 35.322384 35.326226 35.393769
2 35.446876 35.436236 35.413111 35.338840 35.276135 35.276722 35.330491
3 27.477787 27.376960 27.298817 27.239179 27.249114 27.380852 27.560293
4 27.362065 27.253544 27.175085 27.119611 27.145849 27.320097 27.518127
[5 rows x 49 columns]
For CESM with 2x preindustrial pCO2¶
In [7]:
# For CESM model with 2x pre-industrial CO2, combine the datasets of SAT, SST, SSS and prec into one dataset for further analysis
# Add a column to number the rows within each month consecutively
Lutetian_CESM_2PIC_SAT['Cell'] = Lutetian_CESM_2PIC_SAT.groupby('Month').cumcount() + 1
Lutetian_CESM_2PIC_SST['Cell'] = Lutetian_CESM_2PIC_SST.groupby('Month').cumcount() + 1
Lutetian_CESM_2PIC_SSS['Cell'] = Lutetian_CESM_2PIC_SSS.groupby('Month').cumcount() + 1
Lutetian_CESM_2PIC_prec['Cell'] = Lutetian_CESM_2PIC_prec.groupby('Month').cumcount() + 1
# Pivot the datasets to create separate columns for each month with 2-letter abbreviations
Lutetian_CESM_2PIC_SAT_wide = Lutetian_CESM_2PIC_SAT.pivot(index='Cell', columns='Month', values='Temperature')
Lutetian_CESM_2PIC_SAT_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_CESM_2PIC_SAT_wide.columns]
Lutetian_CESM_2PIC_SST_wide = Lutetian_CESM_2PIC_SST.pivot(index='Cell', columns='Month', values='SST')
Lutetian_CESM_2PIC_SST_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_CESM_2PIC_SST_wide.columns]
Lutetian_CESM_2PIC_SSS_wide = Lutetian_CESM_2PIC_SSS.pivot(index='Cell', columns='Month', values='SSS')
Lutetian_CESM_2PIC_SSS_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_CESM_2PIC_SSS_wide.columns]
Lutetian_CESM_2PIC_prec_wide = Lutetian_CESM_2PIC_prec.pivot(index='Cell', columns='Month', values='Precipitation')
Lutetian_CESM_2PIC_prec_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_CESM_2PIC_prec_wide.columns]
# Reset the index to make 'Cell' a column again
Lutetian_CESM_2PIC_SAT_wide.reset_index(inplace = True)
Lutetian_CESM_2PIC_SST_wide.reset_index(inplace = True)
Lutetian_CESM_2PIC_SSS_wide.reset_index(inplace = True)
Lutetian_CESM_2PIC_prec_wide.reset_index(inplace = True)
# Merge the datasets of SAT, SST, SSS and prec, force suffixes to be added to the column names
# Merge in two steps to circumvent different numbers of cells due to differing spatial resolution in air and ocean models
Lutetian_CESM_2PIC_model = pd.merge(
# Merge SAT and prec data
pd.merge(
Lutetian_CESM_2PIC_SAT_wide.rename(columns = {c: c+'_SAT' for c in Lutetian_CESM_2PIC_SAT_wide.columns if c != 'Cell'}),
Lutetian_CESM_2PIC_prec_wide.rename(columns = {c: c+'_precip' for c in Lutetian_CESM_2PIC_prec_wide.columns if c != 'Cell'}),
on = 'Cell',
how = 'outer'
),
# Merge SST and SSS data
pd.merge(
Lutetian_CESM_2PIC_SST_wide.rename(columns = {c: c+'_SST' for c in Lutetian_CESM_2PIC_SST_wide.columns if c != 'Cell'}),
Lutetian_CESM_2PIC_SSS_wide.rename(columns = {c: c+'_SSS' for c in Lutetian_CESM_2PIC_SSS_wide.columns if c != 'Cell'}),
on = 'Cell',
how = 'outer'
),
on = 'Cell',
how = 'outer'
)
# Display the combined dataset
print("CESM 2x pre-industrial CO2 combined dataset:")
print(Lutetian_CESM_2PIC_model.head())
CESM 2x pre-industrial CO2 combined dataset:
Cell ja_SAT fb_SAT mr_SAT ar_SAT my_SAT jn_SAT \
0 1 8.079706 8.682245 10.292291 13.623804 18.543329 22.827844
1 2 18.723108 19.036798 20.318903 22.775720 26.905450 31.019128
2 3 18.902612 19.163934 20.205408 22.355096 26.210016 30.252496
3 4 19.552850 19.557764 20.425623 22.352350 25.905756 29.882379
4 5 18.329370 18.452631 19.794916 22.507562 27.185938 31.563654
jl_SAT ag_SAT sp_SAT ... mr_SSS ar_SSS my_SSS \
0 25.661005 25.911890 22.544611 ... 35.557816 35.549113 35.578386
1 34.275934 34.816797 31.946375 ... 35.568414 35.559291 35.579439
2 34.047083 34.686151 32.002588 ... 35.488143 35.475190 35.489032
3 33.956262 34.617273 31.891870 ... 28.127362 28.017930 27.871013
4 36.184412 36.466760 32.711786 ... 28.087784 27.952144 27.782063
jn_SSS jl_SSS ag_SSS sp_SSS ot_SSS nv_SSS dc_SSS
0 35.604078 35.612619 35.590057 35.542811 35.520497 35.563135 35.608150
1 35.598084 35.603424 35.595446 35.571139 35.549517 35.570238 35.601316
2 35.499420 35.495488 35.490418 35.487392 35.482942 35.506846 35.529809
3 27.769361 27.677441 27.601284 27.565443 27.592602 27.742316 27.963268
4 27.661411 27.563237 27.489528 27.457962 27.502879 27.701501 27.951535
[5 rows x 49 columns]
For HadCM with 1x preindustrial pCO2 (new model)¶
In [8]:
# For HadCM model with 1x pre-industrial CO2, combine the datasets of SAT, SST, SSS and prec into one dataset for further analysis
# Add a column to number the rows within each month consecutively
Lutetian_HadCM_new_1PIC_SAT['Cell'] = Lutetian_HadCM_new_1PIC_SAT.groupby('Month').cumcount() + 1
Lutetian_HadCM_new_1PIC_SST['Cell'] = Lutetian_HadCM_new_1PIC_SST.groupby('Month').cumcount() + 1
Lutetian_HadCM_new_1PIC_SSS['Cell'] = Lutetian_HadCM_new_1PIC_SSS.groupby('Month').cumcount() + 1
Lutetian_HadCM_new_1PIC_prec['Cell'] = Lutetian_HadCM_new_1PIC_prec.groupby('Month').cumcount() + 1
# Pivot the datasets to create separate columns for each month with 2-letter abbreviations
Lutetian_HadCM_new_1PIC_SAT_wide = Lutetian_HadCM_new_1PIC_SAT.pivot(index='Cell', columns='Month', values='SAT')
Lutetian_HadCM_new_1PIC_SAT_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_new_1PIC_SAT_wide.columns]
Lutetian_HadCM_new_1PIC_SST_wide = Lutetian_HadCM_new_1PIC_SST.pivot(index='Cell', columns='Month', values='SST')
Lutetian_HadCM_new_1PIC_SST_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_new_1PIC_SST_wide.columns]
Lutetian_HadCM_new_1PIC_SSS_wide = Lutetian_HadCM_new_1PIC_SSS.pivot(index='Cell', columns='Month', values='SSS')
Lutetian_HadCM_new_1PIC_SSS_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_new_1PIC_SSS_wide.columns]
Lutetian_HadCM_new_1PIC_prec_wide = Lutetian_HadCM_new_1PIC_prec.pivot(index='Cell', columns='Month', values='Precipitation')
Lutetian_HadCM_new_1PIC_prec_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_new_1PIC_prec_wide.columns]
# Reset the index to make 'Cell' a column again
Lutetian_HadCM_new_1PIC_SAT_wide.reset_index(inplace = True)
Lutetian_HadCM_new_1PIC_SST_wide.reset_index(inplace = True)
Lutetian_HadCM_new_1PIC_SSS_wide.reset_index(inplace = True)
Lutetian_HadCM_new_1PIC_prec_wide.reset_index(inplace = True)
# Merge the datasets of SAT, SST, SSS and prec, force suffixes to be added to the column names
# Merge in two steps to circumvent different numbers of cells due to differing spatial resolution in air and ocean models
Lutetian_HadCM_new_1PIC_model = pd.merge(
# Merge SAT and prec data
pd.merge(
Lutetian_HadCM_new_1PIC_SAT_wide.rename(columns = {c: c+'_SAT' for c in Lutetian_HadCM_new_1PIC_SAT_wide.columns if c != 'Cell'}),
Lutetian_HadCM_new_1PIC_prec_wide.rename(columns = {c: c+'_precip' for c in Lutetian_HadCM_new_1PIC_prec_wide.columns if c != 'Cell'}),
on = 'Cell',
how = 'outer'
),
# Merge SST and SSS data
pd.merge(
Lutetian_HadCM_new_1PIC_SST_wide.rename(columns = {c: c+'_SST' for c in Lutetian_HadCM_new_1PIC_SST_wide.columns if c != 'Cell'}),
Lutetian_HadCM_new_1PIC_SSS_wide.rename(columns = {c: c+'_SSS' for c in Lutetian_HadCM_new_1PIC_SSS_wide.columns if c != 'Cell'}),
on = 'Cell',
how = 'outer'
),
on = 'Cell',
how = 'outer'
)
# Display the combined dataset
print("HadCM 1x pre-industrial CO2 combined dataset:")
print(Lutetian_HadCM_new_1PIC_model.head())
HadCM 1x pre-industrial CO2 combined dataset:
Cell ja_SAT fb_SAT mr_SAT ar_SAT my_SAT jn_SAT \
0 1 8.052789 7.992517 8.733209 10.359064 13.972986 19.524438
1 2 5.543665 5.446466 6.303369 8.327386 12.788965 18.906274
2 3 5.441797 5.020135 5.603723 7.323083 11.379724 17.331293
3 4 11.657343 11.682520 12.354303 13.548639 16.459161 21.680658
4 5 3.336206 5.344659 8.210504 11.033441 15.833429 20.868097
jl_SAT ag_SAT sp_SAT ... mr_SSS ar_SSS my_SSS \
0 24.154474 25.112024 22.214838 ... 36.579043 36.582041 36.582377
1 23.355554 24.378473 21.271326 ... 36.590740 36.600344 36.610681
2 22.398523 23.914362 21.047418 ... 36.406383 36.429290 36.462274
3 25.439905 26.119257 24.086908 ... 36.593636 36.589672 36.575392
4 23.159937 23.440515 20.537500 ... 36.549568 36.556936 36.568931
jn_SSS jl_SSS ag_SSS sp_SSS ot_SSS nv_SSS dc_SSS
0 36.562211 36.522156 36.497449 36.542234 36.608670 36.635368 36.626951
1 36.615911 36.585364 36.565986 36.597584 36.633123 36.636892 36.619583
2 36.489640 36.471493 36.454039 36.492532 36.519571 36.500253 36.461642
3 36.536135 36.464259 36.407722 36.455007 36.527968 36.575614 36.601006
4 36.551240 36.519668 36.495510 36.528441 36.575906 36.555548 36.545291
[5 rows x 49 columns]
For HadCM with 2x preindustrial pCO2 (new model)¶
In [9]:
# For HadCM model with 2x pre-industrial CO2, combine the datasets of SAT, SST, SSS and prec into one dataset for further analysis
# Add a column to number the rows within each month consecutively
Lutetian_HadCM_new_2PIC_SAT['Cell'] = Lutetian_HadCM_new_2PIC_SAT.groupby('Month').cumcount() + 1
Lutetian_HadCM_new_2PIC_SST['Cell'] = Lutetian_HadCM_new_2PIC_SST.groupby('Month').cumcount() + 1
Lutetian_HadCM_new_2PIC_SSS['Cell'] = Lutetian_HadCM_new_2PIC_SSS.groupby('Month').cumcount() + 1
Lutetian_HadCM_new_2PIC_prec['Cell'] = Lutetian_HadCM_new_2PIC_prec.groupby('Month').cumcount() + 1
# Pivot the datasets to create separate columns for each month with 2-letter abbreviations
Lutetian_HadCM_new_2PIC_SAT_wide = Lutetian_HadCM_new_2PIC_SAT.pivot(index='Cell', columns='Month', values='SAT')
Lutetian_HadCM_new_2PIC_SAT_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_new_2PIC_SAT_wide.columns]
Lutetian_HadCM_new_2PIC_SST_wide = Lutetian_HadCM_new_2PIC_SST.pivot(index='Cell', columns='Month', values='SST')
Lutetian_HadCM_new_2PIC_SST_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_new_2PIC_SST_wide.columns]
Lutetian_HadCM_new_2PIC_SSS_wide = Lutetian_HadCM_new_2PIC_SSS.pivot(index='Cell', columns='Month', values='SSS')
Lutetian_HadCM_new_2PIC_SSS_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_new_2PIC_SSS_wide.columns]
Lutetian_HadCM_new_2PIC_prec_wide = Lutetian_HadCM_new_2PIC_prec.pivot(index='Cell', columns='Month', values='Precipitation')
Lutetian_HadCM_new_2PIC_prec_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_new_2PIC_prec_wide.columns]
# Reset the index to make 'Cell' a column again
Lutetian_HadCM_new_2PIC_SAT_wide.reset_index(inplace = True)
Lutetian_HadCM_new_2PIC_SST_wide.reset_index(inplace = True)
Lutetian_HadCM_new_2PIC_SSS_wide.reset_index(inplace = True)
Lutetian_HadCM_new_2PIC_prec_wide.reset_index(inplace = True)
# Merge the datasets of SAT, SST, SSS and prec, force suffixes to be added to the column names
# Merge in two steps to circumvent different numbers of cells due to differing spatial resolution in air and ocean models
Lutetian_HadCM_new_2PIC_model = pd.merge(
# Merge SAT and prec data
pd.merge(
Lutetian_HadCM_new_2PIC_SAT_wide.rename(columns = {c: c+'_SAT' for c in Lutetian_HadCM_new_2PIC_SAT_wide.columns if c != 'Cell'}),
Lutetian_HadCM_new_2PIC_prec_wide.rename(columns = {c: c+'_precip' for c in Lutetian_HadCM_new_2PIC_prec_wide.columns if c != 'Cell'}),
on = 'Cell',
how = 'outer'
),
# Merge SST and SSS data
pd.merge(
Lutetian_HadCM_new_2PIC_SST_wide.rename(columns = {c: c+'_SST' for c in Lutetian_HadCM_new_2PIC_SST_wide.columns if c != 'Cell'}),
Lutetian_HadCM_new_2PIC_SSS_wide.rename(columns = {c: c+'_SSS' for c in Lutetian_HadCM_new_2PIC_SSS_wide.columns if c != 'Cell'}),
on = 'Cell',
how = 'outer'
),
on = 'Cell',
how = 'outer'
)
# Display the combined dataset
print("HadCM 2x pre-industrial CO2 combined dataset:")
print(Lutetian_HadCM_new_2PIC_model.head())
HadCM 2x pre-industrial CO2 combined dataset:
Cell ja_SAT fb_SAT mr_SAT ar_SAT my_SAT jn_SAT \
0 1 12.032495 11.765405 12.540948 14.017786 17.638818 22.951166
1 2 10.032343 9.614069 10.567499 12.368372 16.857782 23.125818
2 3 10.042474 9.279749 9.883508 11.388208 15.628229 21.994348
3 4 15.231805 14.956903 15.680139 16.795190 19.790338 24.812463
4 5 7.854364 8.944025 11.926355 14.481989 19.159235 24.058344
jl_SAT ag_SAT sp_SAT ... mr_SSS ar_SSS my_SSS \
0 27.410181 28.291254 25.576105 ... 36.880476 36.889930 36.874808
1 27.034113 27.580316 24.560754 ... 36.887639 36.901384 36.904206
2 26.338739 27.108881 24.157251 ... 36.695585 36.722629 36.756006
3 28.288263 28.865594 26.970605 ... 36.891104 36.888574 36.860925
4 26.157434 26.275842 23.426965 ... 36.842747 36.854991 36.855491
jn_SSS jl_SSS ag_SSS sp_SSS ot_SSS nv_SSS dc_SSS
0 36.864941 36.848321 36.827491 36.892424 36.946852 36.962674 36.939401
1 36.921163 36.901155 36.878949 36.930710 36.959289 36.949357 36.918651
2 36.786631 36.773049 36.764045 36.815244 36.832087 36.800560 36.756923
3 36.831438 36.801560 36.726469 36.785466 36.852630 36.891959 36.908774
4 36.838816 36.819720 36.786201 36.836641 36.885977 36.861411 36.844403
[5 rows x 49 columns]
For HadCM with 1056 ppm pCO2 (new model)¶
In [10]:
# For HadCM model with 1056 ppm CO2, combine the datasets of SAT, SST, SSS and prec into one dataset for further analysis
# Add a column to number the rows within each month consecutively
Lutetian_HadCM_new_1056ppm_SAT['Cell'] = Lutetian_HadCM_new_1056ppm_SAT.groupby('Month').cumcount() + 1
Lutetian_HadCM_new_1056ppm_SST['Cell'] = Lutetian_HadCM_new_1056ppm_SST.groupby('Month').cumcount() + 1
Lutetian_HadCM_new_1056ppm_SSS['Cell'] = Lutetian_HadCM_new_1056ppm_SSS.groupby('Month').cumcount() + 1
Lutetian_HadCM_new_1056ppm_prec['Cell'] = Lutetian_HadCM_new_1056ppm_prec.groupby('Month').cumcount() + 1
# Pivot the datasets to create separate columns for each month with 2-letter abbreviations
Lutetian_HadCM_new_1056ppm_SAT_wide = Lutetian_HadCM_new_1056ppm_SAT.pivot(index='Cell', columns='Month', values='SAT')
Lutetian_HadCM_new_1056ppm_SAT_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_new_1056ppm_SAT_wide.columns]
Lutetian_HadCM_new_1056ppm_SST_wide = Lutetian_HadCM_new_1056ppm_SST.pivot(index='Cell', columns='Month', values='SST')
Lutetian_HadCM_new_1056ppm_SST_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_new_1056ppm_SST_wide.columns]
Lutetian_HadCM_new_1056ppm_SSS_wide = Lutetian_HadCM_new_1056ppm_SSS.pivot(index='Cell', columns='Month', values='SSS')
Lutetian_HadCM_new_1056ppm_SSS_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_new_1056ppm_SSS_wide.columns]
Lutetian_HadCM_new_1056ppm_prec_wide = Lutetian_HadCM_new_1056ppm_prec.pivot(index='Cell', columns='Month', values='Precipitation')
Lutetian_HadCM_new_1056ppm_prec_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_new_1056ppm_prec_wide.columns]
# Reset the index to make 'Cell' a column again
Lutetian_HadCM_new_1056ppm_SAT_wide.reset_index(inplace = True)
Lutetian_HadCM_new_1056ppm_SST_wide.reset_index(inplace = True)
Lutetian_HadCM_new_1056ppm_SSS_wide.reset_index(inplace = True)
Lutetian_HadCM_new_1056ppm_prec_wide.reset_index(inplace = True)
# Merge the datasets of SAT, SST, SSS and prec, force suffixes to be added to the column names
# Merge in two steps to circumvent different numbers of cells due to differing spatial resolution in air and ocean models
Lutetian_HadCM_new_1056ppm_model = pd.merge(
# Merge SAT and prec data
pd.merge(
Lutetian_HadCM_new_1056ppm_SAT_wide.rename(columns = {c: c+'_SAT' for c in Lutetian_HadCM_new_1056ppm_SAT_wide.columns if c != 'Cell'}),
Lutetian_HadCM_new_1056ppm_prec_wide.rename(columns = {c: c+'_precip' for c in Lutetian_HadCM_new_1056ppm_prec_wide.columns if c != 'Cell'}),
on = 'Cell',
how = 'outer'
),
# Merge SST and SSS data
pd.merge(
Lutetian_HadCM_new_1056ppm_SST_wide.rename(columns = {c: c+'_SST' for c in Lutetian_HadCM_new_1056ppm_SST_wide.columns if c != 'Cell'}),
Lutetian_HadCM_new_1056ppm_SSS_wide.rename(columns = {c: c+'_SSS' for c in Lutetian_HadCM_new_1056ppm_SSS_wide.columns if c != 'Cell'}),
on = 'Cell',
how = 'outer'
),
on = 'Cell',
how = 'outer'
)
# Display the combined dataset
print("HadCM 1056 ppm CO2 combined dataset:")
print(Lutetian_HadCM_new_1056ppm_model.head())
HadCM 1056 ppm CO2 combined dataset:
Cell ja_SAT fb_SAT mr_SAT ar_SAT my_SAT jn_SAT \
0 1 14.752985 14.494897 14.980402 16.575220 20.000818 25.204980
1 2 12.996912 12.753046 13.208704 15.260828 19.392999 25.608850
2 3 13.127679 12.599512 12.679742 14.343317 18.218500 24.699243
3 4 17.809625 17.621484 17.975031 19.288171 22.094263 26.878717
4 5 11.005304 12.533258 14.417230 17.510217 21.609277 26.559656
jl_SAT ag_SAT sp_SAT ... mr_SSS ar_SSS my_SSS \
0 29.662347 30.615137 28.027460 ... 37.107916 37.122627 37.129847
1 29.630823 30.056573 27.234857 ... 37.100452 37.119542 37.140229
2 28.905939 29.489587 26.775018 ... 36.894937 36.932385 36.979232
3 30.409326 31.094934 29.279382 ... 37.126426 37.127387 37.107266
4 29.221490 29.027551 26.355951 ... 37.061939 37.079618 37.092974
jn_SSS jl_SSS ag_SSS sp_SSS ot_SSS nv_SSS dc_SSS
0 37.127376 37.156189 37.201068 37.261104 37.257688 37.229975 37.179673
1 37.165682 37.184126 37.210042 37.259688 37.232547 37.185048 37.135684
2 37.024214 37.038639 37.058643 37.104572 37.072104 37.012180 36.958759
3 37.073434 37.093539 37.108810 37.146504 37.171028 37.184294 37.174637
4 37.076982 37.090555 37.117251 37.161991 37.165776 37.111025 37.079348
[5 rows x 49 columns]
For HadCM with 2x preindustrial pCO2 (old model)¶
In [11]:
# For old HadCM model with 2x pre-industrial CO2, combine the datasets of SAT, SST, SSS and prec into one dataset for further analysis
# Add a column to number the rows within each month consecutively
Lutetian_HadCM_old_2PIC_SAT['Cell'] = Lutetian_HadCM_old_2PIC_SAT.groupby('Month').cumcount() + 1
Lutetian_HadCM_old_2PIC_SST['Cell'] = Lutetian_HadCM_old_2PIC_SST.groupby('Month').cumcount() + 1
Lutetian_HadCM_old_2PIC_SSS['Cell'] = Lutetian_HadCM_old_2PIC_SSS.groupby('Month').cumcount() + 1
Lutetian_HadCM_old_2PIC_prec['Cell'] = Lutetian_HadCM_old_2PIC_prec.groupby('Month').cumcount() + 1
# Pivot the datasets to create separate columns for each month with 2-letter abbreviations
Lutetian_HadCM_old_2PIC_SAT_wide = Lutetian_HadCM_old_2PIC_SAT.pivot(index='Cell', columns='Month', values='SAT')
Lutetian_HadCM_old_2PIC_SAT_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_old_2PIC_SAT_wide.columns]
Lutetian_HadCM_old_2PIC_SST_wide = Lutetian_HadCM_old_2PIC_SST.pivot(index='Cell', columns='Month', values='SST')
Lutetian_HadCM_old_2PIC_SST_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_old_2PIC_SST_wide.columns]
Lutetian_HadCM_old_2PIC_SSS_wide = Lutetian_HadCM_old_2PIC_SSS.pivot(index='Cell', columns='Month', values='SSS')
Lutetian_HadCM_old_2PIC_SSS_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_old_2PIC_SSS_wide.columns]
Lutetian_HadCM_old_2PIC_prec_wide = Lutetian_HadCM_old_2PIC_prec.pivot(index='Cell', columns='Month', values='Precipitation')
Lutetian_HadCM_old_2PIC_prec_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_old_2PIC_prec_wide.columns]
# Reset the index to make 'Cell' a column again
Lutetian_HadCM_old_2PIC_SAT_wide.reset_index(inplace = True)
Lutetian_HadCM_old_2PIC_SST_wide.reset_index(inplace = True)
Lutetian_HadCM_old_2PIC_SSS_wide.reset_index(inplace = True)
Lutetian_HadCM_old_2PIC_prec_wide.reset_index(inplace = True)
# Merge the datasets of SAT, SST, SSS and prec, force suffixes to be added to the column names
# Merge in two steps to circumvent different numbers of cells due to differing spatial resolution in air and ocean models
Lutetian_HadCM_old_2PIC_model = pd.merge(
# Merge SAT and prec data
pd.merge(
Lutetian_HadCM_old_2PIC_SAT_wide.rename(columns = {c: c+'_SAT' for c in Lutetian_HadCM_old_2PIC_SAT_wide.columns if c != 'Cell'}),
Lutetian_HadCM_old_2PIC_prec_wide.rename(columns = {c: c+'_precip' for c in Lutetian_HadCM_old_2PIC_prec_wide.columns if c != 'Cell'}),
on = 'Cell',
how = 'outer'
),
# Merge SST and SSS data
pd.merge(
Lutetian_HadCM_old_2PIC_SST_wide.rename(columns = {c: c+'_SST' for c in Lutetian_HadCM_old_2PIC_SST_wide.columns if c != 'Cell'}),
Lutetian_HadCM_old_2PIC_SSS_wide.rename(columns = {c: c+'_SSS' for c in Lutetian_HadCM_old_2PIC_SSS_wide.columns if c != 'Cell'}),
on = 'Cell',
how = 'outer'
),
on = 'Cell',
how = 'outer'
)
# Display the combined dataset
print("HadCM 2x pre-industrial CO2 combined dataset:")
print(Lutetian_HadCM_old_2PIC_model.head())
HadCM 2x pre-industrial CO2 combined dataset:
Cell ja_SAT fb_SAT mr_SAT ar_SAT my_SAT jn_SAT \
0 1 16.109460 16.027917 16.557794 17.969568 20.876367 24.644067
1 2 14.491327 14.465814 15.096796 16.632349 20.268671 25.111902
2 3 14.220056 13.856958 14.220026 15.771631 19.406030 24.685876
3 4 18.878229 18.639429 18.971124 20.211633 22.895258 26.576044
4 5 10.043237 12.065576 15.218744 18.920587 23.262933 28.577478
jl_SAT ag_SAT sp_SAT ... mr_SSS ar_SSS my_SSS \
0 28.467523 30.818384 29.538446 ... 43.969082 43.947790 43.934935
1 29.014185 31.189355 29.456750 ... 44.181548 44.176541 44.191296
2 28.935297 30.628656 28.646417 ... 44.309432 44.306594 44.347039
3 29.851801 31.372522 30.517450 ... 44.129675 44.117172 44.110881
4 31.001825 31.300806 27.688562 ... 44.226661 44.231675 44.226539
jn_SSS jl_SSS ag_SSS sp_SSS ot_SSS nv_SSS dc_SSS
0 43.978868 44.011678 44.061833 44.047975 43.960946 43.904051 43.891164
1 44.264250 44.308143 44.352010 44.343193 44.260797 44.201793 44.162164
2 44.436311 44.486742 44.510761 44.496772 44.395210 44.342191 44.312135
3 44.158615 44.235987 44.316041 44.293411 44.185926 44.109325 44.078983
4 44.259989 44.324560 44.404327 44.392665 44.300962 44.235267 44.207007
[5 rows x 49 columns]
For HadCM with 4x preindustrial pCO2 (old model)¶
In [12]:
# For old HadCM model with 4x pre-industrial CO2, combine the datasets of SAT, SST, SSS and prec into one dataset for further analysis
# Add a column to number the rows within each month consecutively
Lutetian_HadCM_old_4PIC_SAT['Cell'] = Lutetian_HadCM_old_4PIC_SAT.groupby('Month').cumcount() + 1
Lutetian_HadCM_old_4PIC_SST['Cell'] = Lutetian_HadCM_old_4PIC_SST.groupby('Month').cumcount() + 1
Lutetian_HadCM_old_4PIC_SSS['Cell'] = Lutetian_HadCM_old_4PIC_SSS.groupby('Month').cumcount() + 1
Lutetian_HadCM_old_4PIC_prec['Cell'] = Lutetian_HadCM_old_4PIC_prec.groupby('Month').cumcount() + 1
# Pivot the datasets to create separate columns for each month with 2-letter abbreviations
Lutetian_HadCM_old_4PIC_SAT_wide = Lutetian_HadCM_old_4PIC_SAT.pivot(index='Cell', columns='Month', values='SAT')
Lutetian_HadCM_old_4PIC_SAT_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_old_4PIC_SAT_wide.columns]
Lutetian_HadCM_old_4PIC_SST_wide = Lutetian_HadCM_old_4PIC_SST.pivot(index='Cell', columns='Month', values='SST')
Lutetian_HadCM_old_4PIC_SST_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_old_4PIC_SST_wide.columns]
Lutetian_HadCM_old_4PIC_SSS_wide = Lutetian_HadCM_old_4PIC_SSS.pivot(index='Cell', columns='Month', values='SSS')
Lutetian_HadCM_old_4PIC_SSS_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_old_4PIC_SSS_wide.columns]
Lutetian_HadCM_old_4PIC_prec_wide = Lutetian_HadCM_old_4PIC_prec.pivot(index='Cell', columns='Month', values='Precipitation')
Lutetian_HadCM_old_4PIC_prec_wide.columns = [month_abbreviations[col - 1] for col in Lutetian_HadCM_old_4PIC_prec_wide.columns]
# Reset the index to make 'Cell' a column again
Lutetian_HadCM_old_4PIC_SAT_wide.reset_index(inplace = True)
Lutetian_HadCM_old_4PIC_SST_wide.reset_index(inplace = True)
Lutetian_HadCM_old_4PIC_SSS_wide.reset_index(inplace = True)
Lutetian_HadCM_old_4PIC_prec_wide.reset_index(inplace = True)
# Merge the datasets of SAT, SST, SSS and prec, force suffixes to be added to the column names
# Merge in two steps to circumvent different numbers of cells due to differing spatial resolution in air and ocean models
Lutetian_HadCM_old_4PIC_model = pd.merge(
# Merge SAT and prec data
pd.merge(
Lutetian_HadCM_old_4PIC_SAT_wide.rename(columns = {c: c+'_SAT' for c in Lutetian_HadCM_old_4PIC_SAT_wide.columns if c != 'Cell'}),
Lutetian_HadCM_old_4PIC_prec_wide.rename(columns = {c: c+'_precip' for c in Lutetian_HadCM_old_4PIC_prec_wide.columns if c != 'Cell'}),
on = 'Cell',
how = 'outer'
),
# Merge SST and SSS data
pd.merge(
Lutetian_HadCM_old_4PIC_SST_wide.rename(columns = {c: c+'_SST' for c in Lutetian_HadCM_old_4PIC_SST_wide.columns if c != 'Cell'}),
Lutetian_HadCM_old_4PIC_SSS_wide.rename(columns = {c: c+'_SSS' for c in Lutetian_HadCM_old_4PIC_SSS_wide.columns if c != 'Cell'}),
on = 'Cell',
how = 'outer'
),
on = 'Cell',
how = 'outer'
)
# Display the combined dataset
print("HadCM 4x pre-industrial CO2 combined dataset:")
print(Lutetian_HadCM_old_4PIC_model.head())
HadCM 4x pre-industrial CO2 combined dataset:
Cell ja_SAT fb_SAT mr_SAT ar_SAT my_SAT jn_SAT \
0 1 16.109460 16.027917 16.557794 17.969568 20.876367 24.644067
1 2 14.491327 14.465814 15.096796 16.632349 20.268671 25.111902
2 3 14.220056 13.856958 14.220026 15.771631 19.406030 24.685876
3 4 18.878229 18.639429 18.971124 20.211633 22.895258 26.576044
4 5 10.043237 12.065576 15.218744 18.920587 23.262933 28.577478
jl_SAT ag_SAT sp_SAT ... mr_SSS ar_SSS my_SSS \
0 28.467523 30.818384 29.538446 ... 43.969082 43.947790 43.934935
1 29.014185 31.189355 29.456750 ... 44.181548 44.176541 44.191296
2 28.935297 30.628656 28.646417 ... 44.309432 44.306594 44.347039
3 29.851801 31.372522 30.517450 ... 44.129675 44.117172 44.110881
4 31.001825 31.300806 27.688562 ... 44.226661 44.231675 44.226539
jn_SSS jl_SSS ag_SSS sp_SSS ot_SSS nv_SSS dc_SSS
0 43.978868 44.011678 44.061833 44.047975 43.960946 43.904051 43.891164
1 44.264250 44.308143 44.352010 44.343193 44.260797 44.201793 44.162164
2 44.436311 44.486742 44.510761 44.496772 44.395210 44.342191 44.312135
3 44.158615 44.235987 44.316041 44.293411 44.185926 44.109325 44.078983
4 44.259989 44.324560 44.404327 44.392665 44.300962 44.235267 44.207007
[5 rows x 49 columns]
Calculate the monthly prior for model SST, SAT, SSS and precipitation values¶
For CESM with 4x preindustrial pCO2¶
In [13]:
# Create list of month names
months = ['ja', 'fb', 'mr', 'ar', 'my', 'jn', 'jl', 'ag', 'sp', 'ot', 'nv', 'dc']
# Start by calculating prior means and covariances for CESM model with 4x pre-industrial CO2
# Prior SST, SAT, SSS & precipitation estimates from climate models (mean)
mu_prior_CESM_4PIC_SAT_monthly = np.array(Lutetian_CESM_4PIC_model[[f"{month}_SAT" for month in months]].mean(axis=0, skipna=True))
mu_prior_CESM_4PIC_SST_monthly = np.array(Lutetian_CESM_4PIC_model[[f"{month}_SST" for month in months]].mean(axis=0, skipna=True))
mu_prior_CESM_4PIC_SSS_monthly = np.array(Lutetian_CESM_4PIC_model[[f"{month}_SSS" for month in months]].mean(axis=0, skipna=True))
mu_prior_CESM_4PIC_precip_monthly = np.array(Lutetian_CESM_4PIC_model[[f"{month}_precip" for month in months]].mean(axis=0, skipna=True))
# Covariance between months in prior SST, SAT, SSS, and precip estimates from climate models (covariance matrix)
cov_prior_CESM_4PIC_SAT_monthly = np.cov(Lutetian_CESM_4PIC_model[[f"{month}_SAT" for month in months]].dropna(), rowvar=False)
cov_prior_CESM_4PIC_SST_monthly = np.cov(Lutetian_CESM_4PIC_model[[f"{month}_SST" for month in months]].dropna(), rowvar=False)
cov_prior_CESM_4PIC_SSS_monthly = np.cov(Lutetian_CESM_4PIC_model[[f"{month}_SSS" for month in months]].dropna(), rowvar=False)
cov_prior_CESM_4PIC_precip_monthly = np.cov(Lutetian_CESM_4PIC_model[[f"{month}_precip" for month in months]].dropna(), rowvar=False)
# Store copy of original prior means to keep when later updating the prior
mu_prior_CESM_4PIC_SAT_monthly_original, cov_prior_CESM_4PIC_SAT_monthly_original = mu_prior_CESM_4PIC_SAT_monthly.copy(), cov_prior_CESM_4PIC_SAT_monthly.copy()
mu_prior_CESM_4PIC_SST_monthly_original, cov_prior_CESM_4PIC_SST_monthly_original = mu_prior_CESM_4PIC_SST_monthly.copy(), cov_prior_CESM_4PIC_SST_monthly.copy()
mu_prior_CESM_4PIC_SSS_monthly_original, cov_prior_CESM_4PIC_SSS_monthly_original = mu_prior_CESM_4PIC_SSS_monthly.copy(), cov_prior_CESM_4PIC_SSS_monthly.copy()
mu_prior_CESM_4PIC_precip_monthly_original, cov_prior_CESM_4PIC_precip_monthly_original = mu_prior_CESM_4PIC_precip_monthly.copy(), cov_prior_CESM_4PIC_precip_monthly.copy()
# Extract the standard deviations (uncertainty) from the covariance matrix
std_prior_CESM_4PIC_SAT_monthly = np.sqrt(np.diag(cov_prior_CESM_4PIC_SAT_monthly))
std_prior_CESM_4PIC_SST_monthly = np.sqrt(np.diag(cov_prior_CESM_4PIC_SST_monthly))
std_prior_CESM_4PIC_SSS_monthly = np.sqrt(np.diag(cov_prior_CESM_4PIC_SSS_monthly))
std_prior_CESM_4PIC_precip_monthly = np.sqrt(np.diag(cov_prior_CESM_4PIC_precip_monthly))
print("CESM model with 4x pre-industrial CO2 prior means and standard deviations:")
print("SAT Monthly Means:", mu_prior_CESM_4PIC_SAT_monthly)
print("SAT Monthly Std Devs:", std_prior_CESM_4PIC_SAT_monthly)
print("SST Monthly Means:", mu_prior_CESM_4PIC_SST_monthly)
print("SST Monthly Std Devs:", std_prior_CESM_4PIC_SST_monthly)
print("SSS Monthly Means:", mu_prior_CESM_4PIC_SSS_monthly)
print("SSS Monthly Std Devs:", std_prior_CESM_4PIC_SSS_monthly)
print("Precip Monthly Means:", mu_prior_CESM_4PIC_precip_monthly)
print("Precip Monthly Std Devs:", std_prior_CESM_4PIC_precip_monthly)
CESM model with 4x pre-industrial CO2 prior means and standard deviations: SAT Monthly Means: [16.27954224 17.01156006 18.66868896 21.54889648 27.12244995 32.0811853 35.76927734 35.78623779 32.02878784 25.72896606 20.42561768 17.17369751] SAT Monthly Std Devs: [3.46377896 3.10594374 2.78918732 2.54271169 2.46488387 2.73331005 2.85535749 2.646315 2.52596201 3.00791784 3.58824735 3.69933077] SST Monthly Means: [23.86139364 23.17810472 23.14772474 23.92908666 26.57514352 30.58667586 34.10417351 35.48879139 34.18526063 31.27739675 28.24302759 25.51228172] SST Monthly Std Devs: [2.83903042 2.98635231 2.95864974 2.74006009 2.42216397 2.22547687 2.02150675 1.9040936 1.73710814 1.64930877 2.07319756 2.54273385] SSS Monthly Means: [34.48952147 34.48138433 34.46366809 34.44571124 34.43899317 34.43806975 34.41677989 34.40664036 34.40840345 34.436755 34.46977234 34.49277948] SSS Monthly Std Devs: [3.01539682 2.98680818 2.97232063 2.97675101 3.00281989 3.03418516 3.0716477 3.107458 3.13625919 3.14157102 3.10472103 3.05326323] Precip Monthly Means: [2.05036495 2.09002108 2.13109892 1.96715635 1.40643449 1.6901619 2.09515585 1.98018534 1.94212635 1.63982346 1.82765013 1.94334188] Precip Monthly Std Devs: [0.66564033 0.62619878 0.56043175 0.67673041 0.71392551 0.98128657 1.25333983 1.00710893 0.75627296 0.48859499 0.68684095 0.68028201]
For CESM with 2x preindustrial pCO2¶
In [14]:
# Now calculate prior means and covariances for CESM model with 2x pre-industrial CO2
# Prior SST, SAT, SSS & precipitation estimates from climate models (mean)
mu_prior_CESM_2PIC_SAT_monthly = np.array(Lutetian_CESM_2PIC_model[[f"{month}_SAT" for month in months]].mean(axis=0, skipna=True))
mu_prior_CESM_2PIC_SST_monthly = np.array(Lutetian_CESM_2PIC_model[[f"{month}_SST" for month in months]].mean(axis=0, skipna=True))
mu_prior_CESM_2PIC_SSS_monthly = np.array(Lutetian_CESM_2PIC_model[[f"{month}_SSS" for month in months]].mean(axis=0, skipna=True))
mu_prior_CESM_2PIC_precip_monthly = np.array(Lutetian_CESM_2PIC_model[[f"{month}_precip" for month in months]].mean(axis=0, skipna=True))
# Covariance between months in prior SST, SAT, SSS, and precip estimates from climate models (covariance matrix)
cov_prior_CESM_2PIC_SAT_monthly = np.cov(Lutetian_CESM_2PIC_model[[f"{month}_SAT" for month in months]].dropna(), rowvar=False)
cov_prior_CESM_2PIC_SST_monthly = np.cov(Lutetian_CESM_2PIC_model[[f"{month}_SST" for month in months]].dropna(), rowvar=False)
cov_prior_CESM_2PIC_SSS_monthly = np.cov(Lutetian_CESM_2PIC_model[[f"{month}_SSS" for month in months]].dropna(), rowvar=False)
cov_prior_CESM_2PIC_precip_monthly = np.cov(Lutetian_CESM_2PIC_model[[f"{month}_precip" for month in months]].dropna(), rowvar=False)
# Store copy of original prior means to keep when later updating the prior
mu_prior_CESM_2PIC_SAT_monthly_original, cov_prior_CESM_2PIC_SAT_monthly_original = mu_prior_CESM_2PIC_SAT_monthly.copy(), cov_prior_CESM_2PIC_SAT_monthly.copy()
mu_prior_CESM_2PIC_SST_monthly_original, cov_prior_CESM_2PIC_SST_monthly_original = mu_prior_CESM_2PIC_SST_monthly.copy(), cov_prior_CESM_2PIC_SST_monthly.copy()
mu_prior_CESM_2PIC_SSS_monthly_original, cov_prior_CESM_2PIC_SSS_monthly_original = mu_prior_CESM_2PIC_SSS_monthly.copy(), cov_prior_CESM_2PIC_SSS_monthly.copy()
mu_prior_CESM_2PIC_precip_monthly_original, cov_prior_CESM_2PIC_precip_monthly_original = mu_prior_CESM_2PIC_precip_monthly.copy(), cov_prior_CESM_2PIC_precip_monthly.copy()
# Extract the standard deviations (uncertainty) from the covariance matrix
std_prior_CESM_2PIC_SAT_monthly = np.sqrt(np.diag(cov_prior_CESM_2PIC_SAT_monthly))
std_prior_CESM_2PIC_SST_monthly = np.sqrt(np.diag(cov_prior_CESM_2PIC_SST_monthly))
std_prior_CESM_2PIC_SSS_monthly = np.sqrt(np.diag(cov_prior_CESM_2PIC_SSS_monthly))
std_prior_CESM_2PIC_precip_monthly = np.sqrt(np.diag(cov_prior_CESM_2PIC_precip_monthly))
print("---")
print("CESM model with 2x pre-industrial CO2 prior means and standard deviations:")
print("SAT Monthly Means:", mu_prior_CESM_2PIC_SAT_monthly)
print("SAT Monthly Std Devs:", std_prior_CESM_2PIC_SAT_monthly)
print("SST Monthly Means:", mu_prior_CESM_2PIC_SST_monthly)
print("SST Monthly Std Devs:", std_prior_CESM_2PIC_SST_monthly)
print("SSS Monthly Means:", mu_prior_CESM_2PIC_SSS_monthly)
print("SSS Monthly Std Devs:", std_prior_CESM_2PIC_SSS_monthly)
print("Precip Monthly Means:", mu_prior_CESM_2PIC_precip_monthly)
print("Precip Monthly Std Devs:", std_prior_CESM_2PIC_precip_monthly)
--- CESM model with 2x pre-industrial CO2 prior means and standard deviations: SAT Monthly Means: [13.07259888 13.64740356 15.16016968 18.37324585 23.23636963 27.22269897 30.5027002 30.95843628 27.72623169 21.72160767 16.61921631 13.56875732] SAT Monthly Std Devs: [3.54443863 3.25051999 2.97972364 2.6082818 2.44318742 2.633592 2.9258649 2.76327261 2.72785837 3.26765855 3.74834864 3.87666334] SST Monthly Means: [21.09214209 20.50165407 20.45381792 21.3438108 24.00107607 27.76274415 31.12298921 32.43020732 31.14308296 28.27901287 25.30350554 22.60309048] SST Monthly Std Devs: [3.12392276 3.24945387 3.19959003 2.96228485 2.63419216 2.44521968 2.27340414 2.07587422 1.86449504 1.85875098 2.30023504 2.78693935] SSS Monthly Means: [34.58157413 34.5569607 34.53000974 34.49177733 34.47721809 34.47541228 34.46641887 34.48131349 34.52202742 34.56347591 34.58911597 34.59847409] SSS Monthly Std Devs: [2.8600681 2.83254349 2.81830048 2.83097958 2.86959282 2.90697684 2.94569794 2.98781149 3.02031307 3.02348573 2.98133699 2.91080858] Precip Monthly Means: [2.02240836 2.1888688 2.37645928 2.1330658 1.70077639 1.93969147 2.35826096 2.03186492 1.81291405 1.57573304 2.40556723 2.22682322] Precip Monthly Std Devs: [0.71949004 0.82266634 0.74623178 0.7373264 0.8970992 1.16473376 1.52905146 1.05236599 0.73902296 0.47685306 0.73744784 0.91193706]
For new HadCM model with 1x preindustrial pCO2¶
In [15]:
# Calculate prior means and covariances for HadCM model with 1x pre-industrial CO2
# Prior SST, SAT, SSS & precipitation estimates from climate models (mean)
mu_prior_HadCM_new_1PIC_SAT_monthly = np.array(Lutetian_HadCM_new_1PIC_model[[f"{month}_SAT" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_new_1PIC_SST_monthly = np.array(Lutetian_HadCM_new_1PIC_model[[f"{month}_SST" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_new_1PIC_SSS_monthly = np.array(Lutetian_HadCM_new_1PIC_model[[f"{month}_SSS" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_new_1PIC_precip_monthly = np.array(Lutetian_HadCM_new_1PIC_model[[f"{month}_precip" for month in months]].mean(axis=0, skipna=True))
# Covariance between months in prior SST, SAT, SSS, and precip estimates from climate models (covariance matrix)
cov_prior_HadCM_new_1PIC_SAT_monthly = np.cov(Lutetian_HadCM_new_1PIC_model[[f"{month}_SAT" for month in months]].dropna(), rowvar=False)
cov_prior_HadCM_new_1PIC_SST_monthly = np.cov(Lutetian_HadCM_new_1PIC_model[[f"{month}_SST" for month in months]].dropna(), rowvar=False)
cov_prior_HadCM_new_1PIC_SSS_monthly = np.cov(Lutetian_HadCM_new_1PIC_model[[f"{month}_SSS" for month in months]].dropna(), rowvar=False)
cov_prior_HadCM_new_1PIC_precip_monthly = np.cov(Lutetian_HadCM_new_1PIC_model[[f"{month}_precip" for month in months]].dropna(), rowvar=False)
# Store copy of original prior means to keep when later updating the prior
mu_prior_HadCM_new_1PIC_SAT_monthly_original, cov_prior_HadCM_new_1PIC_SAT_monthly_original = mu_prior_HadCM_new_1PIC_SAT_monthly.copy(), cov_prior_HadCM_new_1PIC_SAT_monthly.copy()
mu_prior_HadCM_new_1PIC_SST_monthly_original, cov_prior_HadCM_new_1PIC_SST_monthly_original = mu_prior_HadCM_new_1PIC_SST_monthly.copy(), cov_prior_HadCM_new_1PIC_SST_monthly.copy()
mu_prior_HadCM_new_1PIC_SSS_monthly_original, cov_prior_HadCM_new_1PIC_SSS_monthly_original = mu_prior_HadCM_new_1PIC_SSS_monthly.copy(), cov_prior_HadCM_new_1PIC_SSS_monthly.copy()
mu_prior_HadCM_new_1PIC_precip_monthly_original, cov_prior_HadCM_new_1PIC_precip_monthly_original = mu_prior_HadCM_new_1PIC_precip_monthly.copy(), cov_prior_HadCM_new_1PIC_precip_monthly.copy()
# Extract the standard deviations (uncertainty) from the covariance matrix
std_prior_HadCM_new_1PIC_SAT_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_1PIC_SAT_monthly))
std_prior_HadCM_new_1PIC_SST_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_1PIC_SST_monthly))
std_prior_HadCM_new_1PIC_SSS_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_1PIC_SSS_monthly))
std_prior_HadCM_new_1PIC_precip_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_1PIC_precip_monthly))
print("HadCM model with 1x pre-industrial CO2 prior means and standard deviations:")
print("SAT Monthly Means:", mu_prior_HadCM_new_1PIC_SAT_monthly)
print("SAT Monthly Std Devs:", std_prior_HadCM_new_1PIC_SAT_monthly)
print("SST Monthly Means:", mu_prior_HadCM_new_1PIC_SST_monthly)
print("SST Monthly Std Devs:", std_prior_HadCM_new_1PIC_SST_monthly)
print("SSS Monthly Means:", mu_prior_HadCM_new_1PIC_SSS_monthly)
print("SSS Monthly Std Devs:", std_prior_HadCM_new_1PIC_SSS_monthly)
print("Precip Monthly Means:", mu_prior_HadCM_new_1PIC_precip_monthly)
print("Precip Monthly Std Devs:", std_prior_HadCM_new_1PIC_precip_monthly)
HadCM model with 1x pre-industrial CO2 prior means and standard deviations: SAT Monthly Means: [10.08334503 10.0055481 10.76345469 12.26940816 15.83041026 20.84376678 24.38166707 25.21004893 23.2913503 19.00565236 14.61674144 11.84420675] SAT Monthly Std Devs: [3.96689536 3.6677536 3.37467091 2.96255495 2.3892861 1.69618705 1.01561685 0.897383 1.69453479 2.75833427 3.47391248 3.86029272] SST Monthly Means: [13.71185927 12.85175267 12.7495474 13.53442938 16.28040175 21.56905868 25.37004297 26.3086742 24.58255681 21.0859427 17.70897813 15.26846392] SST Monthly Std Devs: [3.61325925 3.75286553 3.68884027 3.36160861 2.6673752 1.79873409 1.04501078 0.80858375 1.61560915 2.50872528 2.97987362 3.32066194] SSS Monthly Means: [36.29380518 36.28339932 36.28229094 36.29092787 36.28725088 36.26170626 36.24131509 36.20445716 36.23276794 36.29270599 36.31168112 36.30833951] SSS Monthly Std Devs: [0.33686695 0.33061834 0.32995713 0.33377789 0.35726196 0.37809867 0.36099287 0.36809007 0.37801889 0.36607785 0.35702902 0.34699976] Precip Monthly Means: [2.93467813 2.51780503 2.36863809 2.23043843 2.39540224 2.0227101 3.48519517 3.86902922 3.50113248 3.86729931 3.88739363 3.5501087 ] Precip Monthly Std Devs: [0.55099183 0.33959534 0.30486469 0.38027225 0.8389547 1.13985648 1.28457778 0.88043538 0.83027462 0.81630782 0.57832729 0.61808957]
For new HadCM model with 2x preindustrial pCO2¶
In [16]:
# Calculate prior means and covariances for HadCM model with 2x pre-industrial CO2
# Prior SST, SAT, SSS & precipitation estimates from climate models (mean)
mu_prior_HadCM_new_2PIC_SAT_monthly = np.array(Lutetian_HadCM_new_2PIC_model[[f"{month}_SAT" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_new_2PIC_SST_monthly = np.array(Lutetian_HadCM_new_2PIC_model[[f"{month}_SST" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_new_2PIC_SSS_monthly = np.array(Lutetian_HadCM_new_2PIC_model[[f"{month}_SSS" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_new_2PIC_precip_monthly = np.array(Lutetian_HadCM_new_2PIC_model[[f"{month}_precip" for month in months]].mean(axis=0, skipna=True))
# Covariance between months in prior SST, SAT, SSS, and precip estimates from climate models (covariance matrix)
cov_prior_HadCM_new_2PIC_SAT_monthly = np.cov(Lutetian_HadCM_new_2PIC_model[[f"{month}_SAT" for month in months]].dropna(), rowvar=False)
cov_prior_HadCM_new_2PIC_SST_monthly = np.cov(Lutetian_HadCM_new_2PIC_model[[f"{month}_SST" for month in months]].dropna(), rowvar=False)
cov_prior_HadCM_new_2PIC_SSS_monthly = np.cov(Lutetian_HadCM_new_2PIC_model[[f"{month}_SSS" for month in months]].dropna(), rowvar=False)
cov_prior_HadCM_new_2PIC_precip_monthly = np.cov(Lutetian_HadCM_new_2PIC_model[[f"{month}_precip" for month in months]].dropna(), rowvar=False)
# Store copy of original prior means to keep when later updating the prior
mu_prior_HadCM_new_2PIC_SAT_monthly_original, cov_prior_HadCM_new_2PIC_SAT_monthly_original = mu_prior_HadCM_new_2PIC_SAT_monthly.copy(), cov_prior_HadCM_new_2PIC_SAT_monthly.copy()
mu_prior_HadCM_new_2PIC_SST_monthly_original, cov_prior_HadCM_new_2PIC_SST_monthly_original = mu_prior_HadCM_new_2PIC_SST_monthly.copy(), cov_prior_HadCM_new_2PIC_SST_monthly.copy()
mu_prior_HadCM_new_2PIC_SSS_monthly_original, cov_prior_HadCM_new_2PIC_SSS_monthly_original = mu_prior_HadCM_new_2PIC_SSS_monthly.copy(), cov_prior_HadCM_new_2PIC_SSS_monthly.copy()
mu_prior_HadCM_new_2PIC_precip_monthly_original, cov_prior_HadCM_new_2PIC_precip_monthly_original = mu_prior_HadCM_new_2PIC_precip_monthly.copy(), cov_prior_HadCM_new_2PIC_precip_monthly.copy()
# Extract the standard deviations (uncertainty) from the covariance matrix
std_prior_HadCM_new_2PIC_SAT_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_2PIC_SAT_monthly))
std_prior_HadCM_new_2PIC_SST_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_2PIC_SST_monthly))
std_prior_HadCM_new_2PIC_SSS_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_2PIC_SSS_monthly))
std_prior_HadCM_new_2PIC_precip_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_2PIC_precip_monthly))
print("HadCM model with 2x pre-industrial CO2 prior means and standard deviations:")
print("SAT Monthly Means:", mu_prior_HadCM_new_2PIC_SAT_monthly)
print("SAT Monthly Std Devs:", std_prior_HadCM_new_2PIC_SAT_monthly)
print("SST Monthly Means:", mu_prior_HadCM_new_2PIC_SST_monthly)
print("SST Monthly Std Devs:", std_prior_HadCM_new_2PIC_SST_monthly)
print("SSS Monthly Means:", mu_prior_HadCM_new_2PIC_SSS_monthly)
print("SSS Monthly Std Devs:", std_prior_HadCM_new_2PIC_SSS_monthly)
print("Precip Monthly Means:", mu_prior_HadCM_new_2PIC_precip_monthly)
print("Precip Monthly Std Devs:", std_prior_HadCM_new_2PIC_precip_monthly)
HadCM model with 2x pre-industrial CO2 prior means and standard deviations: SAT Monthly Means: [13.87478027 13.46100006 14.24293162 15.6019455 19.14669444 24.01290283 27.19336853 27.86939901 26.06070608 22.21917877 18.0738032 15.42517497] SAT Monthly Std Devs: [3.41347899 3.22229019 2.87469713 2.50385319 1.86477108 0.98233555 0.60279527 0.70411706 1.43557583 2.29931143 2.93579974 3.37321414] SST Monthly Means: [16.72936006 15.87916062 15.81255115 16.6499893 19.50177904 24.63571306 28.09234827 28.87249704 27.32484054 23.97480947 20.65000586 18.21593779] SST Monthly Std Devs: [3.12896351 3.27754316 3.19489358 2.86552162 2.12298285 1.12347457 0.63620505 0.61010611 1.32532831 2.07901319 2.50455562 2.86486584] SSS Monthly Means: [36.58636508 36.57094957 36.57021872 36.58156468 36.56322799 36.53252962 36.54307583 36.51518076 36.55099426 36.60907426 36.62052294 36.60791749] SSS Monthly Std Devs: [0.34892745 0.34228328 0.34178826 0.34698161 0.37435212 0.40162332 0.37570892 0.38237697 0.3973393 0.37730392 0.36687449 0.35679726] Precip Monthly Means: [3.80580454 3.16736692 2.40405854 2.33888872 2.90959791 1.9625486 3.35601807 3.95611436 3.35655003 3.81088675 4.52821999 4.18951223] Precip Monthly Std Devs: [0.74624594 0.55008635 0.35552588 0.43694453 1.02178189 1.04182468 1.29200533 1.14999034 0.7361767 0.88765985 0.78936416 0.72873753]
For new HadCM model with 1056 ppm pCO2¶
In [17]:
# Calculate prior means and covariances for HadCM model with 1056 ppm CO2
# Prior SST, SAT, SSS & precipitation estimates from climate models (mean)
mu_prior_HadCM_new_1056ppm_SAT_monthly = np.array(Lutetian_HadCM_new_1056ppm_model[[f"{month}_SAT" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_new_1056ppm_SST_monthly = np.array(Lutetian_HadCM_new_1056ppm_model[[f"{month}_SST" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_new_1056ppm_SSS_monthly = np.array(Lutetian_HadCM_new_1056ppm_model[[f"{month}_SSS" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_new_1056ppm_precip_monthly = np.array(Lutetian_HadCM_new_1056ppm_model[[f"{month}_precip" for month in months]].mean(axis=0, skipna=True))
# Covariance between months in prior SST, SAT, SSS, and precip estimates from climate models (covariance matrix)
cov_prior_HadCM_new_1056ppm_SAT_monthly = np.cov(Lutetian_HadCM_new_1056ppm_model[[f"{month}_SAT" for month in months]].dropna(), rowvar=False)
cov_prior_HadCM_new_1056ppm_SST_monthly = np.cov(Lutetian_HadCM_new_1056ppm_model[[f"{month}_SST" for month in months]].dropna(), rowvar=False)
cov_prior_HadCM_new_1056ppm_SSS_monthly = np.cov(Lutetian_HadCM_new_1056ppm_model[[f"{month}_SSS" for month in months]].dropna(), rowvar=False)
cov_prior_HadCM_new_1056ppm_precip_monthly = np.cov(Lutetian_HadCM_new_1056ppm_model[[f"{month}_precip" for month in months]].dropna(), rowvar=False)
# Store copy of original prior means to keep when later updating the prior
mu_prior_HadCM_new_1056ppm_SAT_monthly_original, cov_prior_HadCM_new_1056ppm_SAT_monthly_original = mu_prior_HadCM_new_1056ppm_SAT_monthly.copy(), cov_prior_HadCM_new_1056ppm_SAT_monthly.copy()
mu_prior_HadCM_new_1056ppm_SST_monthly_original, cov_prior_HadCM_new_1056ppm_SST_monthly_original = mu_prior_HadCM_new_1056ppm_SST_monthly.copy(), cov_prior_HadCM_new_1056ppm_SST_monthly.copy()
mu_prior_HadCM_new_1056ppm_SSS_monthly_original, cov_prior_HadCM_new_1056ppm_SSS_monthly_original = mu_prior_HadCM_new_1056ppm_SSS_monthly.copy(), cov_prior_HadCM_new_1056ppm_SSS_monthly.copy()
mu_prior_HadCM_new_1056ppm_precip_monthly_original, cov_prior_HadCM_new_1056ppm_precip_monthly_original = mu_prior_HadCM_new_1056ppm_precip_monthly.copy(), cov_prior_HadCM_new_1056ppm_precip_monthly.copy()
# Extract the standard deviations (uncertainty) from the covariance matrix
std_prior_HadCM_new_1056ppm_SAT_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_1056ppm_SAT_monthly))
std_prior_HadCM_new_1056ppm_SST_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_1056ppm_SST_monthly))
std_prior_HadCM_new_1056ppm_SSS_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_1056ppm_SSS_monthly))
std_prior_HadCM_new_1056ppm_precip_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_1056ppm_precip_monthly))
print("HadCM model with 1056 ppm CO2 prior means and standard deviations:")
print("SAT Monthly Means:", mu_prior_HadCM_new_1056ppm_SAT_monthly)
print("SAT Monthly Std Devs:", std_prior_HadCM_new_1056ppm_SAT_monthly)
print("SST Monthly Means:", mu_prior_HadCM_new_1056ppm_SST_monthly)
print("SST Monthly Std Devs:", std_prior_HadCM_new_1056ppm_SST_monthly)
print("SSS Monthly Means:", mu_prior_HadCM_new_1056ppm_SSS_monthly)
print("SSS Monthly Std Devs:", std_prior_HadCM_new_1056ppm_SSS_monthly)
print("Precip Monthly Means:", mu_prior_HadCM_new_1056ppm_precip_monthly)
print("Precip Monthly Std Devs:", std_prior_HadCM_new_1056ppm_precip_monthly)
HadCM model with 1056 ppm CO2 prior means and standard deviations: SAT Monthly Means: [16.54376119 16.33315684 16.66519572 18.1570933 21.33070018 26.04470978 29.27867788 30.05242564 28.38777822 24.68946991 20.37269491 17.89802958] SAT Monthly Std Devs: [3.1136452 2.87241146 2.6653854 2.24775679 1.63278962 0.69198219 0.47930615 0.56291876 1.14972847 2.03401859 2.74423138 3.08483859] SST Monthly Means: [18.93725482 18.20055996 18.07463733 18.94948942 21.65623561 26.49933052 29.90868568 30.89709473 29.50700535 26.32116821 22.74434818 20.38640473] SST Monthly Std Devs: [2.92543007 3.03146388 2.97552998 2.62686596 1.8848678 0.81764338 0.59191858 0.57527782 1.10605321 1.82464118 2.31451485 2.66401625] SSS Monthly Means: [36.81117155 36.78617369 36.78417348 36.79833389 36.79387419 36.76191701 36.79473585 36.81089483 36.85219832 36.87364457 36.871775 36.84308146] SSS Monthly Std Devs: [0.36005944 0.36024212 0.3596727 0.3678925 0.39256506 0.42024895 0.41518531 0.43954986 0.44087248 0.4074775 0.37944107 0.36737629] Precip Monthly Means: [4.56713648 3.91851193 2.74238199 2.21756103 2.6688204 2.25554827 2.59721839 3.43563859 3.46278601 4.34280869 4.56264103 4.84894508] Precip Monthly Std Devs: [0.85407461 0.70612807 0.50598617 0.43407756 1.00076624 1.0245456 1.00411221 1.11605905 0.828573 1.1991117 0.95570044 1.00690122]
For old HadCM model with 2x preindustrial pCO2¶
In [18]:
# Calculate prior means and covariances for HadCM model with 2x pre-industrial CO2
# Prior SST, SAT, SSS & precipitation estimates from climate models (mean)
mu_prior_HadCM_old_2PIC_SAT_monthly = np.array(Lutetian_HadCM_old_2PIC_model[[f"{month}_SAT" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_old_2PIC_SST_monthly = np.array(Lutetian_HadCM_old_2PIC_model[[f"{month}_SST" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_old_2PIC_SSS_monthly = np.array(Lutetian_HadCM_old_2PIC_model[[f"{month}_SSS" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_old_2PIC_precip_monthly = np.array(Lutetian_HadCM_old_2PIC_model[[f"{month}_precip" for month in months]].mean(axis=0, skipna=True))
# Covariance between months in prior SST, SAT, SSS, and precip estimates from climate models (covariance matrix)
cov_prior_HadCM_old_2PIC_SAT_monthly = np.cov(Lutetian_HadCM_old_2PIC_model[[f"{month}_SAT" for month in months]].dropna(), rowvar=False)
cov_prior_HadCM_old_2PIC_SST_monthly = np.cov(Lutetian_HadCM_old_2PIC_model[[f"{month}_SST" for month in months]].dropna(), rowvar=False)
cov_prior_HadCM_old_2PIC_SSS_monthly = np.cov(Lutetian_HadCM_old_2PIC_model[[f"{month}_SSS" for month in months]].dropna(), rowvar=False)
cov_prior_HadCM_old_2PIC_precip_monthly = np.cov(Lutetian_HadCM_old_2PIC_model[[f"{month}_precip" for month in months]].dropna(), rowvar=False)
# Store copy of original prior means to keep when later updating the prior
mu_prior_HadCM_old_2PIC_SAT_monthly_original, cov_prior_HadCM_old_2PIC_SAT_monthly_original = mu_prior_HadCM_old_2PIC_SAT_monthly.copy(), cov_prior_HadCM_old_2PIC_SAT_monthly.copy()
mu_prior_HadCM_old_2PIC_SST_monthly_original, cov_prior_HadCM_old_2PIC_SST_monthly_original = mu_prior_HadCM_old_2PIC_SST_monthly.copy(), cov_prior_HadCM_old_2PIC_SST_monthly.copy()
mu_prior_HadCM_old_2PIC_SSS_monthly_original, cov_prior_HadCM_old_2PIC_SSS_monthly_original = mu_prior_HadCM_old_2PIC_SSS_monthly.copy(), cov_prior_HadCM_old_2PIC_SSS_monthly.copy()
mu_prior_HadCM_old_2PIC_precip_monthly_original, cov_prior_HadCM_old_2PIC_precip_monthly_original = mu_prior_HadCM_old_2PIC_precip_monthly.copy(), cov_prior_HadCM_old_2PIC_precip_monthly.copy()
# Extract the standard deviations (uncertainty) from the covariance matrix
std_prior_HadCM_old_2PIC_SAT_monthly = np.sqrt(np.diag(cov_prior_HadCM_old_2PIC_SAT_monthly))
std_prior_HadCM_old_2PIC_SST_monthly = np.sqrt(np.diag(cov_prior_HadCM_old_2PIC_SST_monthly))
std_prior_HadCM_old_2PIC_SSS_monthly = np.sqrt(np.diag(cov_prior_HadCM_old_2PIC_SSS_monthly))
std_prior_HadCM_old_2PIC_precip_monthly = np.sqrt(np.diag(cov_prior_HadCM_old_2PIC_precip_monthly))
print("HadCM model with 2x pre-industrial CO2 prior means and standard deviations:")
print("SAT Monthly Means:", mu_prior_HadCM_old_2PIC_SAT_monthly)
print("SAT Monthly Std Devs:", std_prior_HadCM_old_2PIC_SAT_monthly)
print("SST Monthly Means:", mu_prior_HadCM_old_2PIC_SST_monthly)
print("SST Monthly Std Devs:", std_prior_HadCM_old_2PIC_SST_monthly)
print("SSS Monthly Means:", mu_prior_HadCM_old_2PIC_SSS_monthly)
print("SSS Monthly Std Devs:", std_prior_HadCM_old_2PIC_SSS_monthly)
print("Precip Monthly Means:", mu_prior_HadCM_old_2PIC_precip_monthly)
print("Precip Monthly Std Devs:", std_prior_HadCM_old_2PIC_precip_monthly)
HadCM model with 2x pre-industrial CO2 prior means and standard deviations: SAT Monthly Means: [17.37342478 17.21628214 17.78856557 19.24039866 22.18971914 26.23706462 29.33261007 30.70993194 29.73895416 26.07219594 21.69050496 18.52393239] SAT Monthly Std Devs: [3.2114442 2.69102368 2.25082291 1.96523166 1.63807297 1.35401718 0.73510388 0.49971448 0.91035189 1.98977278 2.90543435 3.37134836] SST Monthly Means: [19.7125903 18.99473997 18.88936858 19.91672048 22.810782 26.93403435 29.85972058 31.31134917 30.67377489 27.4390127 23.87150418 21.16645553] SST Monthly Std Devs: [2.24990485 2.29966025 2.31215823 2.12468382 1.64393886 1.0585021 0.44918179 0.47817612 0.69576981 1.50967361 1.95781611 2.15044945] SSS Monthly Means: [43.70795882 43.73280867 43.72686184 43.67948156 43.64607803 43.67422238 43.74063267 43.80258416 43.77589559 43.71899047 43.69268966 43.6958935 ] SSS Monthly Std Devs: [0.7396979 0.72425698 0.74107798 0.79608893 0.84202305 0.85804696 0.84220463 0.84309064 0.87106857 0.84498618 0.81758351 0.77582677] Precip Monthly Means: [4.51414761 2.96477545 2.0466914 1.70405398 1.499306 0.98548384 1.2141631 1.94227658 3.96484522 4.89490475 5.10539876 4.79175341] Precip Monthly Std Devs: [0.54851291 0.54980863 0.52847315 0.61988324 0.67752496 0.34351868 0.40517783 0.93230212 0.90520864 0.74675508 0.64169083 0.55874858]
For old HadCM model with 4x preindustrial pCO2¶
In [19]:
# Calculate prior means and covariances for HadCM model with 4x pre-industrial CO2
# Prior SST, SAT, SSS & precipitation estimates from climate models (mean)
mu_prior_HadCM_old_4PIC_SAT_monthly = np.array(Lutetian_HadCM_old_4PIC_model[[f"{month}_SAT" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_old_4PIC_SST_monthly = np.array(Lutetian_HadCM_old_4PIC_model[[f"{month}_SST" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_old_4PIC_SSS_monthly = np.array(Lutetian_HadCM_old_4PIC_model[[f"{month}_SSS" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_old_4PIC_precip_monthly = np.array(Lutetian_HadCM_old_4PIC_model[[f"{month}_precip" for month in months]].mean(axis=0, skipna=True))
# Covariance between months in prior SST, SAT, SSS, and precip estimates from climate models (covariance matrix)
cov_prior_HadCM_old_4PIC_SAT_monthly = np.cov(Lutetian_HadCM_old_4PIC_model[[f"{month}_SAT" for month in months]].dropna(), rowvar=False)
cov_prior_HadCM_old_4PIC_SST_monthly = np.cov(Lutetian_HadCM_old_4PIC_model[[f"{month}_SST" for month in months]].dropna(), rowvar=False)
cov_prior_HadCM_old_4PIC_SSS_monthly = np.cov(Lutetian_HadCM_old_4PIC_model[[f"{month}_SSS" for month in months]].dropna(), rowvar=False)
cov_prior_HadCM_old_4PIC_precip_monthly = np.cov(Lutetian_HadCM_old_4PIC_model[[f"{month}_precip" for month in months]].dropna(), rowvar=False)
# Store copy of original prior means to keep when later updating the prior
mu_prior_HadCM_old_4PIC_SAT_monthly_original, cov_prior_HadCM_old_4PIC_SAT_monthly_original = mu_prior_HadCM_old_4PIC_SAT_monthly.copy(), cov_prior_HadCM_old_4PIC_SAT_monthly.copy()
mu_prior_HadCM_old_4PIC_SST_monthly_original, cov_prior_HadCM_old_4PIC_SST_monthly_original = mu_prior_HadCM_old_4PIC_SST_monthly.copy(), cov_prior_HadCM_old_4PIC_SST_monthly.copy()
mu_prior_HadCM_old_4PIC_SSS_monthly_original, cov_prior_HadCM_old_4PIC_SSS_monthly_original = mu_prior_HadCM_old_4PIC_SSS_monthly.copy(), cov_prior_HadCM_old_4PIC_SSS_monthly.copy()
mu_prior_HadCM_old_4PIC_precip_monthly_original, cov_prior_HadCM_old_4PIC_precip_monthly_original = mu_prior_HadCM_old_4PIC_precip_monthly.copy(), cov_prior_HadCM_old_4PIC_precip_monthly.copy()
# Extract the standard deviations (uncertainty) from the covariance matrix
std_prior_HadCM_old_4PIC_SAT_monthly = np.sqrt(np.diag(cov_prior_HadCM_old_4PIC_SAT_monthly))
std_prior_HadCM_old_4PIC_SST_monthly = np.sqrt(np.diag(cov_prior_HadCM_old_4PIC_SST_monthly))
std_prior_HadCM_old_4PIC_SSS_monthly = np.sqrt(np.diag(cov_prior_HadCM_old_4PIC_SSS_monthly))
std_prior_HadCM_old_4PIC_precip_monthly = np.sqrt(np.diag(cov_prior_HadCM_old_4PIC_precip_monthly))
print("HadCM model with 4x pre-industrial CO2 prior means and standard deviations:")
print("SAT Monthly Means:", mu_prior_HadCM_old_4PIC_SAT_monthly)
print("SAT Monthly Std Devs:", std_prior_HadCM_old_4PIC_SAT_monthly)
print("SST Monthly Means:", mu_prior_HadCM_old_4PIC_SST_monthly)
print("SST Monthly Std Devs:", std_prior_HadCM_old_4PIC_SST_monthly)
print("SSS Monthly Means:", mu_prior_HadCM_old_4PIC_SSS_monthly)
print("SSS Monthly Std Devs:", std_prior_HadCM_old_4PIC_SSS_monthly)
print("Precip Monthly Means:", mu_prior_HadCM_old_4PIC_precip_monthly)
print("Precip Monthly Std Devs:", std_prior_HadCM_old_4PIC_precip_monthly)
HadCM model with 4x pre-industrial CO2 prior means and standard deviations: SAT Monthly Means: [17.37342478 17.21628214 17.78856557 19.24039866 22.18971914 26.23706462 29.33261007 30.70993194 29.73895416 26.07219594 21.69050496 18.52393239] SAT Monthly Std Devs: [3.2114442 2.69102368 2.25082291 1.96523166 1.63807297 1.35401718 0.73510388 0.49971448 0.91035189 1.98977278 2.90543435 3.37134836] SST Monthly Means: [19.7125903 18.99473997 18.88936858 19.91672048 22.810782 26.93403435 29.85972058 31.31134917 30.67377489 27.4390127 23.87150418 21.16645553] SST Monthly Std Devs: [2.24990485 2.29966025 2.31215823 2.12468382 1.64393886 1.0585021 0.44918179 0.47817612 0.69576981 1.50967361 1.95781611 2.15044945] SSS Monthly Means: [43.70795882 43.73280867 43.72686184 43.67948156 43.64607803 43.67422238 43.74063267 43.80258416 43.77589559 43.71899047 43.69268966 43.6958935 ] SSS Monthly Std Devs: [0.7396979 0.72425698 0.74107798 0.79608893 0.84202305 0.85804696 0.84220463 0.84309064 0.87106857 0.84498618 0.81758351 0.77582677] Precip Monthly Means: [4.51414761 2.96477545 2.0466914 1.70405398 1.499306 0.98548384 1.2141631 1.94227658 3.96484522 4.89490475 5.10539876 4.79175341] Precip Monthly Std Devs: [0.54851291 0.54980863 0.52847315 0.61988324 0.67752496 0.34351868 0.40517783 0.93230212 0.90520864 0.74675508 0.64169083 0.55874858]
Plot the monthly priors for all model values¶
In [20]:
# Set dimensions of data
n_models_CESM_4PIC_monthly = len(Lutetian_CESM_4PIC_model["Cell"]) # Find the total number of models
n_models_CESM_2PIC_monthly = len(Lutetian_CESM_2PIC_model["Cell"]) # Find the total number of models
n_models_HadCM_new_1PIC_monthly = len(Lutetian_HadCM_new_1PIC_model["Cell"]) # Find the total number of models
n_models_HadCM_new_2PIC_monthly = len(Lutetian_HadCM_new_2PIC_model["Cell"]) # Find the total number of models
n_models_HadCM_new_1056ppm_monthly = len(Lutetian_HadCM_new_1056ppm_model["Cell"]) # Find the total number of models
n_models_HadCM_old_2PIC_monthly = len(Lutetian_HadCM_old_2PIC_model["Cell"]) # Find the total number of models
n_models_HadCM_old_4PIC_monthly = len(Lutetian_HadCM_old_4PIC_model["Cell"]) # Find the total number of models
# Create a monthly scale for the x-axis
month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] # List full month names
months_scale = np.arange(len(months)) + 1 # Create monthly scale
# Create the figure and axes
fig, axes = plt.subplots(2, 7, figsize=(25, 10), sharex=True, sharey="row")
# ------------- Plot prior distributions for CESM\nmodel with 4x pre-industrial CO2 ------------- #
# Panel 1: Plot the prior distribution for SST and SAT for CESM\nmodel with 4x pre-industrial CO2
axes[0, 0].plot(months_scale, mu_prior_CESM_4PIC_SAT_monthly, label='Prior SAT Mean', marker='o', color='r')
axes[0, 0].plot(months_scale, mu_prior_CESM_4PIC_SST_monthly, label='Prior SST Mean', marker='o', color='b')
# Add 95% confidence intervals for SAT
axes[0, 0].fill_between(
months_scale,
mu_prior_CESM_4PIC_SAT_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SAT_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
mu_prior_CESM_4PIC_SAT_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SAT_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
alpha=0.2, color='r', label='SAT 95% CI'
)
# Add 95% confidence intervals for SST
axes[0, 0].fill_between(
months_scale,
mu_prior_CESM_4PIC_SST_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SST_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
mu_prior_CESM_4PIC_SST_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SST_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
alpha=0.2, color='b', label='SST 95% CI'
)
axes[0, 0].set_ylim(5, 40) # Set lower limit of temperature y-axis to 15 and upper limit to 40
axes[0, 0].set_title('CESM\n4x pre-industrial CO2')
axes[0, 0].set_ylabel('Temperature (°C)')
axes[0, 0].legend(loc = "upper left")
axes[0, 0].grid(True)
# Panel 2: Plot the prior distribution for SSS and precipitation for CESM\nmodel with 4x pre-industrial CO2
axes[1, 0].plot(months_scale, mu_prior_CESM_4PIC_SSS_monthly, label='Prior SSS Mean', marker='o', color='g')
ax2 = axes[1, 0].twinx() # Create a secondary y-axis for precipitation
ax2.plot(months_scale, mu_prior_CESM_4PIC_precip_monthly, label='Prior Precipitation Mean', marker='o', color='purple')
# Add 95% confidence intervals for SSS
axes[1, 0].fill_between(
months_scale,
mu_prior_CESM_4PIC_SSS_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SSS_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
mu_prior_CESM_4PIC_SSS_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SSS_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
alpha=0.2, color='g', label='SSS 95% CI'
)
# Add 95% confidence intervals for precipitation
ax2.fill_between(
months_scale,
mu_prior_CESM_4PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_precip_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
mu_prior_CESM_4PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_precip_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
alpha=0.2, color='purple', label='Precipitation 95% CI'
)
axes[1, 0].set_ylabel('SSS (psu)', color='g')
axes[1, 0].set_ylim(30, 50) # Set lower limit of SSS y-axis to 30 and upper limit to 45
ax2.set_ylabel('')
ax2.set_ylim(0, 7) # Set lower limit of precipitation y-axis to 0 and upper limit to 7
ax2.set_yticklabels([]) # Hide y-tick labels for SSS to reduce clutter
axes[1, 0].set_title('CESM\n4x pre-industrial CO2')
axes[1, 0].legend(loc='upper left')
ax2.legend(loc='upper right')
axes[1, 0].grid(True)
# ------------- Plot prior distributions for CESM\nmodel with 2x pre-industrial CO2 ------------- #
# Panel 3: Plot the prior distribution for SST and SAT for CESM\nmodel with 2x pre-industrial CO2
axes[0, 1].plot(months_scale, mu_prior_CESM_2PIC_SAT_monthly, label='Prior SAT Mean', marker='o', color='r')
axes[0, 1].plot(months_scale, mu_prior_CESM_2PIC_SST_monthly, label='Prior SST Mean', marker='o', color='b')
# Add 95% confidence intervals for SAT
axes[0, 1].fill_between(
months_scale,
mu_prior_CESM_2PIC_SAT_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SAT_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_SAT_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SAT_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
alpha=0.2, color='r', label='SAT 95% CI'
)
# Add 95% confidence intervals for SST
axes[0, 1].fill_between(
months_scale,
mu_prior_CESM_2PIC_SST_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SST_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_SST_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SST_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
alpha=0.2, color='b', label='SST 95% CI'
)
axes[0, 1].set_ylim(5, 40) # Set lower limit of temperature y-axis to 15 and upper limit to 40
axes[0, 1].set_title('CESM\n2x pre-industrial CO2')
axes[0, 1].set_ylabel('')
axes[0, 1].legend(loc = "upper left")
axes[0, 1].grid(True)
# Panel 4: Plot the prior distribution for SSS and precipitation for CESM\nmodel with 2x pre-industrial CO2
axes[1, 1].plot(months_scale, mu_prior_CESM_2PIC_SSS_monthly, label='Prior SSS Mean', marker='o', color='g')
ax4 = axes[1, 1].twinx() # Create a secondary y-axis for precipitation
ax4.plot(months_scale, mu_prior_CESM_2PIC_precip_monthly, label='Prior Precipitation Mean', marker='o', color='purple')
# Add 95% confidence intervals for SSS
axes[1, 1].fill_between(
months_scale,
mu_prior_CESM_2PIC_SSS_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SSS_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_SSS_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SSS_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
alpha=0.2, color='g', label='SSS 95% CI'
)
# Add 95% confidence intervals for precipitation
ax4.fill_between(
months_scale,
mu_prior_CESM_2PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_precip_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_precip_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
alpha=0.2, color='purple', label='Precipitation 95% CI'
)
axes[1, 1].set_ylabel('')
axes[1, 1].set_ylim(30, 50) # Set lower limit of SSS y-axis to 30 and upper limit to 45
# axes[1, 1].set_yticklabels([]) # Hide SSS y-axis tick labels
# ax4.set_ylabel('Precipitation (mm/day)', color='purple')
ax4.set_yticklabels([]) # Hide precipitation y-axis tick labels
ax4.set_ylim(0, 7) # Set lower limit of precipitation y-axis to 0 and upper limit to 7
axes[1, 1].set_title('CESM\n2x pre-industrial CO2')
axes[1, 1].legend(loc="upper left")
ax4.legend(loc="upper right")
axes[1, 1].grid(True)
# ------------- Plot prior distributions for new HadCM model with 1x pre-industrial CO2 ------------- #
# Panel 5: Plot the prior distribution for SST and SAT for HadCM model with 1x pre-industrial CO2
axes[0, 2].plot(months_scale, mu_prior_HadCM_new_1PIC_SAT_monthly, label='Prior SAT Mean', marker='o', color='r')
axes[0, 2].plot(months_scale, mu_prior_HadCM_new_1PIC_SST_monthly, label='Prior SST Mean', marker='o', color='b')
# Add 95% confidence intervals for SAT
axes[0, 2].fill_between(
months_scale,
mu_prior_HadCM_new_1PIC_SAT_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SAT_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
mu_prior_HadCM_new_1PIC_SAT_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SAT_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
alpha=0.2, color='r', label='SAT 95% CI'
)
# Add 95% confidence intervals for SST
axes[0, 2].fill_between(
months_scale,
mu_prior_HadCM_new_1PIC_SST_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SST_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
mu_prior_HadCM_new_1PIC_SST_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SST_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
alpha=0.2, color='b', label='SST 95% CI'
)
axes[0, 2].set_ylim(5, 40) # Set lower limit of temperature y-axis to 15 and upper limit to 40
axes[0, 2].set_title('HadCM (new)\n1x pre-industrial CO2')
axes[0, 2].set_ylabel('')
axes[0, 2].legend(loc = "upper left")
axes[0, 2].grid(True)
# Panel 6: Plot the prior distribution for SSS and precipitation for HadCM model with 1x pre-industrial CO2
axes[1, 2].plot(months_scale, mu_prior_HadCM_new_1PIC_SSS_monthly, label='Prior SSS Mean', marker='o', color='g')
ax6 = axes[1, 2].twinx() # Create a secondary y-axis for precipitation
ax6.plot(months_scale, mu_prior_HadCM_new_1PIC_precip_monthly, label='Prior Precipitation Mean', marker='o', color='purple')
# Add 95% confidence intervals for SSS
axes[1, 2].fill_between(
months_scale,
mu_prior_HadCM_new_1PIC_SSS_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SSS_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
mu_prior_HadCM_new_1PIC_SSS_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SSS_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
alpha=0.2, color='g', label='SSS 95% CI'
)
# Add 95% confidence intervals for precipitation
ax6.fill_between(
months_scale,
mu_prior_HadCM_new_1PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_precip_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
mu_prior_HadCM_new_1PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_precip_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
alpha=0.2, color='purple', label='Precipitation 95% CI'
)
axes[1, 2].set_ylabel('')
axes[1, 2].set_ylim(30, 50) # Set lower limit of SSS y-axis to 30 and upper limit to 45
# axes[1, 2].set_yticklabels([]) # Hide SSS y-axis tick labels
# ax6.set_ylabel('Precipitation (mm/day)', color='purple')
ax6.set_yticklabels([]) # Hide precipitation y-axis tick labels
ax6.set_ylim(0, 7) # Set lower limit of precipitation y-axis to 0 and upper limit to 7
axes[1, 2].set_title('HadCM (new)\n1x pre-industrial CO2')
axes[1, 2].legend(loc="upper left")
ax6.legend(loc="upper right")
axes[1, 2].grid(True)
# --------------- Plot prior distributions for new HadCM model with 2x pre-industrial CO2 --------------- #
# Panel 7: Plot the prior distribution for SST and SAT for HadCM model with 2x pre-industrial CO2
axes[0, 3].plot(months_scale, mu_prior_HadCM_new_2PIC_SAT_monthly, label='Prior SAT Mean', marker='o', color='r')
axes[0, 3].plot(months_scale, mu_prior_HadCM_new_2PIC_SST_monthly, label='Prior SST Mean', marker='o', color='b')
# Add 95% confidence intervals for SAT
axes[0, 3].fill_between(
months_scale,
mu_prior_HadCM_new_2PIC_SAT_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SAT_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
mu_prior_HadCM_new_2PIC_SAT_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SAT_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
alpha=0.2, color='r', label='SAT 95% CI'
)
# Add 95% confidence intervals for SST
axes[0, 3].fill_between(
months_scale,
mu_prior_HadCM_new_2PIC_SST_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SST_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
mu_prior_HadCM_new_2PIC_SST_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SST_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
alpha=0.2, color='b', label='SST 95% CI'
)
axes[0, 3].set_ylim(5, 40) # Set lower limit of temperature y-axis to 15 and upper limit to 40
axes[0, 3].set_title('HadCM (new)\n2x pre-industrial CO2')
axes[0, 3].set_ylabel('')
axes[0, 3].legend(loc = "upper left")
axes[0, 3].grid(True)
# Panel 8: Plot the prior distribution for SSS and precipitation for HadCM model with 2x pre-industrial CO2
axes[1, 3].plot(months_scale, mu_prior_HadCM_new_2PIC_SSS_monthly, label='Prior SSS Mean', marker='o', color='g')
ax8 = axes[1, 3].twinx() # Create a secondary y-axis for precipitation
ax8.plot(months_scale, mu_prior_HadCM_new_2PIC_precip_monthly, label='Prior Precipitation Mean', marker='o', color='purple')
# Add 95% confidence intervals for SSS
axes[1, 3].fill_between(
months_scale,
mu_prior_HadCM_new_2PIC_SSS_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SSS_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
mu_prior_HadCM_new_2PIC_SSS_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SSS_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
alpha=0.2, color='g', label='SSS 95% CI'
)
# Add 95% confidence intervals for precipitation
ax8.fill_between(
months_scale,
mu_prior_HadCM_new_2PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_precip_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
mu_prior_HadCM_new_2PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_precip_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
alpha=0.2, color='purple', label='Precipitation 95% CI'
)
axes[1, 3].set_ylabel('')
axes[1, 3].set_ylim(30, 50) # Set lower limit of SSS y-axis to 30 and upper limit to 45
# axes[1, 3].set_yticklabels([]) # Hide SSS y-axis tick labels
# ax8.set_ylabel('Precipitation (mm/day)', color='purple')
ax8.set_yticklabels([]) # Hide precipitation y-axis tick labels
ax8.set_ylim(0, 7) # Set lower limit of precipitation y-axis to 0 and upper limit to 7
axes[1, 3].set_title('HadCM (new)\n2x pre-industrial CO2')
axes[1, 3].legend(loc="upper left")
ax8.legend(loc="upper right")
axes[1, 3].grid(True)
# --------------- Plot prior distributions for new HadCM model with 1056ppm CO2 --------------- #
# Panel 9: Plot the prior distribution for SST and SAT for HadCM model with 1056ppm CO2
axes[0, 4].plot(months_scale, mu_prior_HadCM_new_1056ppm_SAT_monthly, label='Prior SAT Mean', marker='o', color='r')
axes[0, 4].plot(months_scale, mu_prior_HadCM_new_1056ppm_SST_monthly, label='Prior SST Mean', marker='o', color='b')
# Add 95% confidence intervals for SAT
axes[0, 4].fill_between(
months_scale,
mu_prior_HadCM_new_1056ppm_SAT_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SAT_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
mu_prior_HadCM_new_1056ppm_SAT_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SAT_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
alpha=0.2, color='r', label='SAT 95% CI'
)
# Add 95% confidence intervals for SST
axes[0, 4].fill_between(
months_scale,
mu_prior_HadCM_new_1056ppm_SST_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SST_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
mu_prior_HadCM_new_1056ppm_SST_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SST_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
alpha=0.2, color='b', label='SST 95% CI'
)
axes[0, 4].set_ylim(5, 40) # Set lower limit of temperature y-axis to 15 and upper limit to 40
axes[0, 4].set_title('HadCM (new)\n1056ppm CO2')
axes[0, 4].set_ylabel('')
axes[0, 4].legend(loc = "upper left")
axes[0, 4].grid(True)
# Panel 10: Plot the prior distribution for SSS and precipitation for HadCM model with 1056ppm CO2
axes[1, 4].plot(months_scale, mu_prior_HadCM_new_1056ppm_SSS_monthly, label='Prior SSS Mean', marker='o', color='g')
ax10 = axes[1, 4].twinx() # Create a secondary y-axis for precipitation
ax10.plot(months_scale, mu_prior_HadCM_new_1056ppm_precip_monthly, label='Prior Precipitation Mean', marker='o', color='purple')
# Add 95% confidence intervals for SSS
axes[1, 4].fill_between(
months_scale,
mu_prior_HadCM_new_1056ppm_SSS_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SSS_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
mu_prior_HadCM_new_1056ppm_SSS_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SSS_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
alpha=0.2, color='g', label='SSS 95% CI'
)
# Add 95% confidence intervals for precipitation
ax10.fill_between(
months_scale,
mu_prior_HadCM_new_1056ppm_precip_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_precip_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
mu_prior_HadCM_new_1056ppm_precip_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_precip_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
alpha=0.2, color='purple', label='Precipitation 95% CI'
)
axes[1, 4].set_ylabel('')
axes[1, 4].set_ylim(30, 50) # Set lower limit of SSS y-axis to 30 and upper limit to 45
# axes[1, 4].set_yticklabels([]) # Hide SSS y-axis tick labels
# ax10.set_ylabel('Precipitation (mm/day)', color='purple')
ax10.set_yticklabels([]) # Hide precipitation y-axis tick labels
ax10.set_ylim(0, 7) # Set lower limit of precipitation y-axis to 0 and upper limit to 7
axes[1, 4].set_title('HadCM (new)\n1056ppm CO2')
axes[1, 4].legend(loc="upper left")
ax10.legend(loc="upper right")
axes[1, 4].grid(True)
# --------------- Plot prior distributions for old HadCM model with 4x pre-industrial CO2 --------------- #
# Panel 11: Plot the prior distribution for SST and SAT for HadCM model with 4x pre-industrial CO2
axes[0, 5].plot(months_scale, mu_prior_HadCM_old_4PIC_SAT_monthly, label='Prior SAT Mean', marker='o', color='r')
axes[0, 5].plot(months_scale, mu_prior_HadCM_old_4PIC_SST_monthly, label='Prior SST Mean', marker='o', color='b')
# Add 95% confidence intervals for SAT
axes[0, 5].fill_between(
months_scale,
mu_prior_HadCM_old_4PIC_SAT_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SAT_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
mu_prior_HadCM_old_4PIC_SAT_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SAT_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
alpha=0.2, color='r', label='SAT 95% CI'
)
# Add 95% confidence intervals for SST
axes[0, 5].fill_between(
months_scale,
mu_prior_HadCM_old_4PIC_SST_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SST_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
mu_prior_HadCM_old_4PIC_SST_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SST_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
alpha=0.2, color='b', label='SST 95% CI'
)
axes[0, 5].set_ylim(5, 40) # Set lower limit of temperature y-axis to 15 and upper limit to 40
axes[0, 5].set_title('HadCM (old)\n4x pre-industrial CO2')
axes[0, 5].set_ylabel('')
axes[0, 5].legend(loc = "upper left")
axes[0, 5].grid(True)
# Panel 12: Plot the prior distribution for SSS and precipitation for HadCM model with 4x pre-industrial CO2
axes[1, 5].plot(months_scale, mu_prior_HadCM_old_4PIC_SSS_monthly, label='Prior SSS Mean', marker='o', color='g')
ax12 = axes[1, 5].twinx() # Create a secondary y-axis for precipitation
ax12.plot(months_scale, mu_prior_HadCM_old_4PIC_precip_monthly, label='Prior Precipitation Mean', marker='o', color='purple')
# Add 95% confidence intervals for SSS
axes[1, 5].fill_between(
months_scale,
mu_prior_HadCM_old_4PIC_SSS_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SSS_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
mu_prior_HadCM_old_4PIC_SSS_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SSS_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
alpha=0.2, color='g', label='SSS 95% CI'
)
# Add 95% confidence intervals for precipitation
ax12.fill_between(
months_scale,
mu_prior_HadCM_old_4PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_precip_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
mu_prior_HadCM_old_4PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_precip_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
alpha=0.2, color='purple', label='Precipitation 95% CI'
)
axes[1, 5].set_ylabel('')
axes[1, 5].set_ylim(30, 50) # Set lower limit of SSS y-axis to 30 and upper limit to 45
# axes[1, 5].set_yticklabels([]) # Hide SSS y-axis tick labels
# ax12.set_ylabel('Precipitation (mm/day)', color='purple')
ax12.set_yticklabels([]) # Hide precipitation y-axis tick labels
ax12.set_ylim(0, 7) # Set lower limit of precipitation y-axis to 0 and upper limit to 7
axes[1, 5].set_title('HadCM (old)\n4x pre-industrial CO2')
axes[1, 5].legend(loc="upper left")
ax12.legend(loc="upper right")
axes[1, 5].grid(True)
# --------------- Plot prior distributions for old HadCM model with 2x pre-industrial CO2 --------------- #
# Panel 13: Plot the prior distribution for SST and SAT for HadCM model with 2x pre-industrial CO2
axes[0, 6].plot(months_scale, mu_prior_HadCM_old_2PIC_SAT_monthly, label='Prior SAT Mean', marker='o', color='r')
axes[0, 6].plot(months_scale, mu_prior_HadCM_old_2PIC_SST_monthly, label='Prior SST Mean', marker='o', color='b')
# Add 95% confidence intervals for SAT
axes[0, 6].fill_between(
months_scale,
mu_prior_HadCM_old_2PIC_SAT_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SAT_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
mu_prior_HadCM_old_2PIC_SAT_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SAT_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
alpha=0.2, color='r', label='SAT 95% CI'
)
# Add 95% confidence intervals for SST
axes[0, 6].fill_between(
months_scale,
mu_prior_HadCM_old_2PIC_SST_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SST_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
mu_prior_HadCM_old_2PIC_SST_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SST_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
alpha=0.2, color='b', label='SST 95% CI'
)
axes[0, 6].set_ylim(5, 40) # Set lower limit of temperature y-axis to 15 and upper limit to 40
axes[0, 6].set_title('HadCM (old)\n2x pre-industrial CO2')
axes[0, 6].set_ylabel('')
axes[0, 6].legend(loc = "upper left")
axes[0, 6].grid(True)
# Panel 14: Plot the prior distribution for SSS and precipitation for HadCM model with 2x pre-industrial CO2
axes[1, 6].plot(months_scale, mu_prior_HadCM_old_2PIC_SSS_monthly, label='Prior SSS Mean', marker='o', color='g')
ax14 = axes[1, 6].twinx() # Create a secondary y-axis for precipitation
ax14.plot(months_scale, mu_prior_HadCM_old_2PIC_precip_monthly, label='Prior Precipitation Mean', marker='o', color='purple')
# Add 95% confidence intervals for SSS
axes[1, 6].fill_between(
months_scale,
mu_prior_HadCM_old_2PIC_SSS_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SSS_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
mu_prior_HadCM_old_2PIC_SSS_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SSS_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
alpha=0.2, color='g', label='SSS 95% CI'
)
# Add 95% confidence intervals for precipitation
ax14.fill_between(
months_scale,
mu_prior_HadCM_old_2PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_precip_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
mu_prior_HadCM_old_2PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_precip_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
alpha=0.2, color='purple', label='Precipitation 95% CI'
)
axes[1, 6].set_ylabel('')
axes[1, 6].set_ylim(30, 50) # Set lower limit of SSS y-axis to 30 and upper limit to 45
# axes[1, 6].set_yticklabels([]) # Hide SSS y-axis tick labels
ax14.set_ylabel('Precipitation (mm/day)', color='purple')
ax14.set_ylim(0, 7) # Set lower limit of precipitation y-axis to 0 and upper limit to 7
axes[1, 6].set_title('HadCM (old)\n2x pre-industrial CO2')
axes[1, 6].legend(loc="upper left")
ax14.legend(loc="upper right")
axes[1, 6].grid(True)
# Update the x-axis with month names
for ax in axes[1, :]:
ax.set_xticks(months_scale)
ax.set_xticklabels(month_names, rotation=45)
# Add overall figure title
fig.suptitle('Prior Distributions of Monthly SST, SAT, SSS, and Precipitation for Various Climate Models with different pCO2 forcing', fontsize=16)
Out[20]:
Text(0.5, 0.98, 'Prior Distributions of Monthly SST, SAT, SSS, and Precipitation for Various Climate Models with different pCO2 forcing')
Convert SAT and SST model data to D47 domain using the regression by Daëron and Vermeesch (2023) and propagate uncertainty in the calibration¶
For CESM with 4x perindustrial pCO2¶
In [21]:
# Apply T47()-function from the D47calib package to all SAT columns
# First for the CESM model with 4x pre-industrial CO2
# Identify the SAT and SST columns
SAT_CESM_4PIC_columns = [col for col in Lutetian_CESM_4PIC_model.columns if col.endswith('_SAT')]
SST_CESM_4PIC_columns = [col for col in Lutetian_CESM_4PIC_model.columns if col.endswith('_SST')]
# Apply the conversion function to the SAT columns and add new columns for D47 and D47_SE
for col in SAT_CESM_4PIC_columns:
base_col_name = col.replace('_SAT', '') # Remove the '_SAT' suffix from the column name
Lutetian_CESM_4PIC_model[f'{base_col_name}_SAT_D47'], Lutetian_CESM_4PIC_model[f'{base_col_name}_SAT_D47_SE'] = zip(*Lutetian_CESM_4PIC_model[col].apply(
lambda x: D47c.OGLS23.T47(T = x) if not pd.isna(x) else (np.nan, np.nan)
)) # Use zip() to unpack the tuple returned by the apply() method and apply the T47()-function to each value in the column
for col in SST_CESM_4PIC_columns:
base_col_name = col.replace('_SST', '') # Remove the '_SST' suffix from the column name
Lutetian_CESM_4PIC_model[f'{base_col_name}_SST_D47'], Lutetian_CESM_4PIC_model[f'{base_col_name}_SST_D47_SE'] = zip(*Lutetian_CESM_4PIC_model[col].apply(
lambda x: D47c.OGLS23.T47(T = x) if not pd.isna(x) else (np.nan, np.nan)
)) # Use zip() to unpack the tuple returned by the apply() method and apply the T47()-function to each value in the column
# Display the combined data with D47 and D47_SE columns
D47_CESM_4PIC_columns = [col for col in Lutetian_CESM_4PIC_model.columns if col.endswith('_D47')]
D47_se_CESM_4PIC_columns = [col for col in Lutetian_CESM_4PIC_model.columns if '_D47_SE' in col]
print("D47 values for all CESM model 4x preindustrial pCO2 outcomes:\n", Lutetian_CESM_4PIC_model[D47_CESM_4PIC_columns].head())
print("Calibration standard errors for all CESM model 4x preindustrial pCO2 outcomes:\n", Lutetian_CESM_4PIC_model[D47_se_CESM_4PIC_columns].head())
D47 values for all CESM model 4x preindustrial pCO2 outcomes:
ja_SAT_D47 fb_SAT_D47 mr_SAT_D47 ar_SAT_D47 my_SAT_D47 jn_SAT_D47 \
0 0.637865 0.635067 0.629115 0.619502 0.601307 0.584664
1 0.603134 0.602008 0.598014 0.591188 0.578009 0.564439
2 0.602866 0.601969 0.598808 0.592691 0.580329 0.567315
3 0.601023 0.600939 0.598426 0.592938 0.581667 0.568903
4 0.604475 0.603903 0.599502 0.591387 0.576345 0.561918
jl_SAT_D47 ag_SAT_D47 sp_SAT_D47 ot_SAT_D47 ... mr_SST_D47 \
0 0.575942 0.575647 0.588334 0.607248 ... 0.593324
1 0.554885 0.553952 0.563022 0.577000 ... 0.594240
2 0.556444 0.554857 0.563225 0.577214 ... 0.595136
3 0.557261 0.555379 0.563453 0.576950 ... 0.618591
4 0.549188 0.549164 0.560136 0.577425 ... 0.618968
ar_SST_D47 my_SST_D47 jn_SST_D47 jl_SST_D47 ag_SST_D47 sp_SST_D47 \
0 0.591086 0.583574 0.572417 0.564044 0.559876 0.562770
1 0.592472 0.585470 0.574402 0.566375 0.562104 0.564462
2 0.593459 0.586555 0.575418 0.567460 0.563169 0.565401
3 0.615362 0.605418 0.592590 0.582142 0.577727 0.579656
4 0.615934 0.606080 0.593130 0.582374 0.577869 0.579768
ot_SST_D47 nv_SST_D47 dc_SST_D47
0 0.570493 0.579090 0.586671
1 0.571625 0.580172 0.587853
2 0.572431 0.581026 0.589019
3 0.586429 0.597502 0.608002
4 0.586786 0.597919 0.608058
[5 rows x 24 columns]
Calibration standard errors for all CESM model 4x preindustrial pCO2 outcomes:
ja_SAT_D47_SE fb_SAT_D47_SE mr_SAT_D47_SE ar_SAT_D47_SE my_SAT_D47_SE \
0 0.001252 0.001233 0.001196 0.001144 0.001073
1 0.001079 0.001075 0.001065 0.001051 0.001041
2 0.001078 0.001075 0.001067 0.001054 0.001041
3 0.001073 0.001072 0.001066 0.001054 0.001042
4 0.001083 0.001081 0.001069 0.001052 0.001041
jn_SAT_D47_SE jl_SAT_D47_SE ag_SAT_D47_SE sp_SAT_D47_SE ot_SAT_D47_SE \
0 0.001044 0.001041 0.001041 0.001047 0.001092
1 0.001051 0.001070 0.001072 0.001053 0.001041
2 0.001047 0.001066 0.001070 0.001053 0.001041
3 0.001046 0.001064 0.001069 0.001053 0.001041
4 0.001055 0.001085 0.001085 0.001059 0.001041
... mr_SST_D47_SE ar_SST_D47_SE my_SST_D47_SE jn_SST_D47_SE \
0 ... 0.001055 0.001051 0.001043 0.001043
1 ... 0.001057 0.001053 0.001044 0.001042
2 ... 0.001058 0.001055 0.001045 0.001041
3 ... 0.001140 0.001125 0.001086 0.001054
4 ... 0.001141 0.001127 0.001088 0.001055
jl_SST_D47_SE ag_SST_D47_SE sp_SST_D47_SE ot_SST_D47_SE nv_SST_D47_SE \
0 0.001052 0.001059 0.001054 0.001044 0.001041
1 0.001049 0.001055 0.001051 0.001043 0.001041
2 0.001047 0.001053 0.001050 0.001043 0.001042
3 0.001042 0.001041 0.001041 0.001045 0.001064
4 0.001042 0.001041 0.001041 0.001046 0.001065
dc_SST_D47_SE
0 0.001045
1 0.001047
2 0.001048
3 0.001095
4 0.001095
[5 rows x 24 columns]
For CESM with 2x perindustrial pCO2¶
In [22]:
# Convert temperature data for the CESM model with 2x pre-industrial CO2
# Identify the SAT and SST columns
SAT_CESM_2PIC_columns = [col for col in Lutetian_CESM_2PIC_model.columns if col.endswith('_SAT')]
SST_CESM_2PIC_columns = [col for col in Lutetian_CESM_2PIC_model.columns if col.endswith('_SST')]
# Apply the conversion function to the SAT columns and add new columns for D47 and D47_SE
for col in SAT_CESM_2PIC_columns:
base_col_name = col.replace('_SAT', '') # Remove the '_SAT' suffix from the column name
Lutetian_CESM_2PIC_model[f'{base_col_name}_SAT_D47'], Lutetian_CESM_2PIC_model[f'{base_col_name}_SAT_D47_SE'] = zip(*Lutetian_CESM_2PIC_model[col].apply(
lambda x: D47c.OGLS23.T47(T = x) if not pd.isna(x) else (np.nan, np.nan)
)) # Use zip() to unpack the tuple returned by the apply() method and apply the T47()-function to each value in the column
for col in SST_CESM_2PIC_columns:
base_col_name = col.replace('_SST', '') # Remove the '_SST' suffix from the column name
Lutetian_CESM_2PIC_model[f'{base_col_name}_SST_D47'], Lutetian_CESM_2PIC_model[f'{base_col_name}_SST_D47_SE'] = zip(*Lutetian_CESM_2PIC_model[col].apply(
lambda x: D47c.OGLS23.T47(T = x) if not pd.isna(x) else (np.nan, np.nan)
)) # Use zip() to unpack the tuple returned by the apply() method and apply the T47()-function to each value in the column
# Display the combined data with D47 and D47_SE columns
D47_CESM_2PIC_columns = [col for col in Lutetian_CESM_2PIC_model.columns if col.endswith('_D47')]
D47_se_CESM_2PIC_columns = [col for col in Lutetian_CESM_2PIC_model.columns if '_D47_SE' in col]
print("D47 values for all CESM model 2x preindustrial pCO2 outcomes:\n", Lutetian_CESM_2PIC_model[D47_CESM_2PIC_columns].head())
print("Calibration standard errors for all CESM model 2x preindustrial pCO2 outcomes:\n", Lutetian_CESM_2PIC_model[D47_se_CESM_2PIC_columns].head())
D47 values for all CESM model 2x preindustrial pCO2 outcomes:
ja_SAT_D47 fb_SAT_D47 mr_SAT_D47 ar_SAT_D47 my_SAT_D47 jn_SAT_D47 \
0 0.649217 0.647051 0.641333 0.629812 0.613530 0.600021
1 0.612951 0.611943 0.607858 0.600181 0.587709 0.575798
2 0.612374 0.611535 0.608217 0.601482 0.589772 0.577980
3 0.610292 0.610277 0.607520 0.601490 0.590680 0.579040
4 0.614221 0.613823 0.609521 0.601010 0.586881 0.574258
jl_SAT_D47 ag_SAT_D47 sp_SAT_D47 ot_SAT_D47 ... mr_SST_D47 \
0 0.591412 0.590661 0.600895 0.619948 ... 0.601218
1 0.566713 0.565232 0.573181 0.587373 ... 0.602052
2 0.567341 0.565589 0.573023 0.587203 ... 0.602959
3 0.567591 0.565777 0.573334 0.586829 ... 0.629461
4 0.561525 0.560765 0.571039 0.588141 ... 0.629846
ar_SST_D47 my_SST_D47 jn_SST_D47 jl_SST_D47 ag_SST_D47 sp_SST_D47 \
0 0.598485 0.590787 0.579938 0.571354 0.567425 0.570273
1 0.599915 0.592725 0.582065 0.573740 0.569557 0.571820
2 0.600939 0.593798 0.583144 0.574862 0.570641 0.572771
3 0.625603 0.615248 0.602450 0.592397 0.587444 0.589301
4 0.626263 0.615955 0.603027 0.592655 0.587575 0.589482
ot_SST_D47 nv_SST_D47 dc_SST_D47
0 0.578342 0.587379 0.595560
1 0.579378 0.588410 0.596721
2 0.580137 0.589270 0.597940
3 0.596974 0.608338 0.619456
4 0.597385 0.608808 0.619465
[5 rows x 24 columns]
Calibration standard errors for all CESM model 2x preindustrial pCO2 outcomes:
ja_SAT_D47_SE fb_SAT_D47_SE mr_SAT_D47_SE ar_SAT_D47_SE my_SAT_D47_SE \
0 0.001335 0.001318 0.001276 0.001200 0.001117
1 0.001114 0.001110 0.001094 0.001070 0.001047
2 0.001112 0.001108 0.001096 0.001074 0.001049
3 0.001103 0.001103 0.001093 0.001074 0.001051
4 0.001120 0.001118 0.001101 0.001073 0.001046
jn_SAT_D47_SE jl_SAT_D47_SE ag_SAT_D47_SE sp_SAT_D47_SE ot_SAT_D47_SE \
0 0.001070 0.001052 0.001050 0.001072 0.001146
1 0.001041 0.001048 0.001050 0.001042 0.001046
2 0.001041 0.001047 0.001050 0.001042 0.001046
3 0.001041 0.001047 0.001049 0.001042 0.001046
4 0.001042 0.001056 0.001057 0.001044 0.001047
... mr_SST_D47_SE ar_SST_D47_SE my_SST_D47_SE jn_SST_D47_SE \
0 ... 0.001073 0.001066 0.001051 0.001041
1 ... 0.001076 0.001070 0.001054 0.001042
2 ... 0.001078 0.001072 0.001056 0.001043
3 ... 0.001198 0.001176 0.001124 0.001077
4 ... 0.001201 0.001180 0.001127 0.001078
jl_SST_D47_SE ag_SST_D47_SE sp_SST_D47_SE ot_SST_D47_SE nv_SST_D47_SE \
0 0.001043 0.001047 0.001044 0.001041 0.001046
1 0.001042 0.001045 0.001043 0.001041 0.001047
2 0.001042 0.001044 0.001043 0.001041 0.001049
3 0.001053 0.001046 0.001049 0.001062 0.001096
4 0.001054 0.001046 0.001049 0.001063 0.001098
dc_SST_D47_SE
0 0.001059
1 0.001062
2 0.001065
3 0.001144
4 0.001144
[5 rows x 24 columns]
ja_SAT_D47_SE fb_SAT_D47_SE mr_SAT_D47_SE ar_SAT_D47_SE my_SAT_D47_SE \
0 0.001335 0.001318 0.001276 0.001200 0.001117
1 0.001114 0.001110 0.001094 0.001070 0.001047
2 0.001112 0.001108 0.001096 0.001074 0.001049
3 0.001103 0.001103 0.001093 0.001074 0.001051
4 0.001120 0.001118 0.001101 0.001073 0.001046
jn_SAT_D47_SE jl_SAT_D47_SE ag_SAT_D47_SE sp_SAT_D47_SE ot_SAT_D47_SE \
0 0.001070 0.001052 0.001050 0.001072 0.001146
1 0.001041 0.001048 0.001050 0.001042 0.001046
2 0.001041 0.001047 0.001050 0.001042 0.001046
3 0.001041 0.001047 0.001049 0.001042 0.001046
4 0.001042 0.001056 0.001057 0.001044 0.001047
... mr_SST_D47_SE ar_SST_D47_SE my_SST_D47_SE jn_SST_D47_SE \
0 ... 0.001073 0.001066 0.001051 0.001041
1 ... 0.001076 0.001070 0.001054 0.001042
2 ... 0.001078 0.001072 0.001056 0.001043
3 ... 0.001198 0.001176 0.001124 0.001077
4 ... 0.001201 0.001180 0.001127 0.001078
jl_SST_D47_SE ag_SST_D47_SE sp_SST_D47_SE ot_SST_D47_SE nv_SST_D47_SE \
0 0.001043 0.001047 0.001044 0.001041 0.001046
1 0.001042 0.001045 0.001043 0.001041 0.001047
2 0.001042 0.001044 0.001043 0.001041 0.001049
3 0.001053 0.001046 0.001049 0.001062 0.001096
4 0.001054 0.001046 0.001049 0.001063 0.001098
dc_SST_D47_SE
0 0.001059
1 0.001062
2 0.001065
3 0.001144
4 0.001144
[5 rows x 24 columns]
For new HadCM model with 1x perindustrial pCO2¶
In [23]:
# Convert temperature data for the HadCM model with 1x pre-industrial CO2
# Identify the SAT and SST columns
SAT_HadCM_new_1PIC_columns = [col for col in Lutetian_HadCM_new_1PIC_model.columns if col.endswith('_SAT')]
SST_HadCM_new_1PIC_columns = [col for col in Lutetian_HadCM_new_1PIC_model.columns if col.endswith('_SST')]
# Apply the conversion function to the SAT columns and add new columns for D47 and D47_SE
for col in SAT_HadCM_new_1PIC_columns:
base_col_name = col.replace('_SAT', '') # Remove the '_SAT' suffix from the column name
Lutetian_HadCM_new_1PIC_model[f'{base_col_name}_SAT_D47'], Lutetian_HadCM_new_1PIC_model[f'{base_col_name}_SAT_D47_SE'] = zip(*Lutetian_HadCM_new_1PIC_model[col].apply(
lambda x: D47c.OGLS23.T47(T = x) if not pd.isna(x) else (np.nan, np.nan)
)) # Use zip() to unpack the tuple returned by the apply() method and apply the T47()-function to each value in the column
for col in SST_HadCM_new_1PIC_columns:
base_col_name = col.replace('_SST', '') # Remove the '_SST' suffix from the column name
Lutetian_HadCM_new_1PIC_model[f'{base_col_name}_SST_D47'], Lutetian_HadCM_new_1PIC_model[f'{base_col_name}_SST_D47_SE'] = zip(*Lutetian_HadCM_new_1PIC_model[col].apply(
lambda x: D47c.OGLS23.T47(T = x) if not pd.isna(x) else (np.nan, np.nan)
)) # Use zip() to unpack the tuple returned by the apply() method and apply the T47()-function to each value in the column
# Display the combined data with D47 and D47_SE columns
D47_HadCM_new_1PIC_columns = [col for col in Lutetian_HadCM_new_1PIC_model.columns if col.endswith('_D47')]
D47_se_HadCM_new_1PIC_columns = [col for col in Lutetian_HadCM_new_1PIC_model.columns if '_D47_SE' in col]
print("D47 values for all HadCM model 1x preindustrial pCO2 outcomes:\n", Lutetian_HadCM_new_1PIC_model[D47_HadCM_new_1PIC_columns].head())
print("Calibration standard errors for all HadCM model 1x preindustrial pCO2 outcomes:\n", Lutetian_HadCM_new_1PIC_model[D47_se_HadCM_new_1PIC_columns].head())
D47 values for all HadCM model 1x preindustrial pCO2 outcomes:
ja_SAT_D47 fb_SAT_D47 mr_SAT_D47 ar_SAT_D47 my_SAT_D47 jn_SAT_D47 \
0 0.649314 0.649532 0.646869 0.641098 0.628628 0.610383
1 0.658490 0.658851 0.655685 0.648325 0.632660 0.612362
2 0.658868 0.660437 0.658268 0.651957 0.637527 0.617463
3 0.636562 0.636475 0.634153 0.630067 0.620324 0.603579
4 0.666775 0.659229 0.648746 0.638734 0.622393 0.606125
jl_SAT_D47 ag_SAT_D47 sp_SAT_D47 ot_SAT_D47 ... mr_SST_D47 \
0 0.595958 0.593060 0.601917 0.618248 ... 0.619820
1 0.598398 0.595278 0.604859 0.623366 ... 0.619261
2 0.601347 0.596689 0.605561 0.623072 ... 0.628556
3 0.592075 0.590043 0.596164 0.609700 ... 0.619637
4 0.598998 0.598137 0.607167 0.626313 ... 0.623051
ar_SST_D47 my_SST_D47 jn_SST_D47 jl_SST_D47 ag_SST_D47 sp_SST_D47 \
0 0.618037 0.611175 0.598163 0.590329 0.588308 0.589935
1 0.617859 0.611340 0.598414 0.590667 0.588558 0.589996
2 0.625196 0.615527 0.600662 0.591871 0.589428 0.591714
3 0.618953 0.613694 0.599588 0.589134 0.586816 0.590283
4 0.622063 0.615181 0.599878 0.589858 0.587718 0.591252
ot_SST_D47 nv_SST_D47 dc_SST_D47
0 0.598029 0.607598 0.614320
1 0.597608 0.606624 0.613628
2 0.600532 0.610380 0.618991
3 0.598287 0.606764 0.612609
4 0.599551 0.609201 0.615761
[5 rows x 24 columns]
Calibration standard errors for all HadCM model 1x preindustrial pCO2 outcomes:
ja_SAT_D47_SE fb_SAT_D47_SE mr_SAT_D47_SE ar_SAT_D47_SE my_SAT_D47_SE \
0 0.001335 0.001337 0.001317 0.001274 0.001193
1 0.001410 0.001413 0.001387 0.001328 0.001218
2 0.001413 0.001427 0.001408 0.001356 0.001250
3 0.001243 0.001243 0.001227 0.001202 0.001148
4 0.001483 0.001416 0.001331 0.001258 0.001159
jn_SAT_D47_SE jl_SAT_D47_SE ag_SAT_D47_SE sp_SAT_D47_SE ot_SAT_D47_SE \
0 0.001104 0.001060 0.001054 0.001075 0.001138
1 0.001112 0.001066 0.001059 0.001084 0.001164
2 0.001134 0.001074 0.001062 0.001086 0.001162
3 0.001080 0.001053 0.001050 0.001061 0.001101
4 0.001088 0.001067 0.001065 0.001092 0.001180
... mr_SST_D47_SE ar_SST_D47_SE my_SST_D47_SE jn_SST_D47_SE \
0 ... 0.001146 0.001137 0.001107 0.001065
1 ... 0.001143 0.001136 0.001108 0.001066
2 ... 0.001193 0.001174 0.001125 0.001072
3 ... 0.001145 0.001141 0.001117 0.001069
4 ... 0.001162 0.001157 0.001124 0.001070
jl_SST_D47_SE ag_SST_D47_SE sp_SST_D47_SE ot_SST_D47_SE nv_SST_D47_SE \
0 0.001050 0.001047 0.001049 0.001065 0.001093
1 0.001050 0.001048 0.001050 0.001064 0.001090
2 0.001052 0.001049 0.001052 0.001071 0.001104
3 0.001048 0.001046 0.001050 0.001066 0.001091
4 0.001049 0.001047 0.001051 0.001069 0.001099
dc_SST_D47_SE
0 0.001120
1 0.001117
2 0.001142
3 0.001113
4 0.001126
[5 rows x 24 columns]
For new HadCM model with 2x perindustrial pCO2¶
In [24]:
# Convert temperature data for the HadCM model with 2x pre-industrial CO2
# Identify the SAT and SST columns
SAT_HadCM_new_2PIC_columns = [col for col in Lutetian_HadCM_new_2PIC_model.columns if col.endswith('_SAT')]
SST_HadCM_new_2PIC_columns = [col for col in Lutetian_HadCM_new_2PIC_model.columns if col.endswith('_SST')]
# Apply the conversion function to the SAT columns and add new columns for D47 and D47_SE
for col in SAT_HadCM_new_2PIC_columns:
base_col_name = col.replace('_SAT', '') # Remove the '_SAT' suffix from the column name
Lutetian_HadCM_new_2PIC_model[f'{base_col_name}_SAT_D47'], Lutetian_HadCM_new_2PIC_model[f'{base_col_name}_SAT_D47_SE'] = zip(*Lutetian_HadCM_new_2PIC_model[col].apply(
lambda x: D47c.OGLS23.T47(T = x) if not pd.isna(x) else (np.nan, np.nan)
)) # Use zip() to unpack the tuple returned by the apply() method and apply the T47()-function to each value in the column
for col in SST_HadCM_new_2PIC_columns:
base_col_name = col.replace('_SST', '') # Remove the '_SST' suffix from the column name
Lutetian_HadCM_new_2PIC_model[f'{base_col_name}_SST_D47'], Lutetian_HadCM_new_2PIC_model[f'{base_col_name}_SST_D47_SE'] = zip(*Lutetian_HadCM_new_2PIC_model[col].apply(
lambda x: D47c.OGLS23.T47(T = x) if not pd.isna(x) else (np.nan, np.nan)
)) # Use zip() to unpack the tuple returned by the apply() method and apply the T47()-function to each value in the column
# Display the combined data with D47 and D47_SE columns
D47_HadCM_new_2PIC_columns = [col for col in Lutetian_HadCM_new_2PIC_model.columns if col.endswith('_D47')]
D47_se_HadCM_new_2PIC_columns = [col for col in Lutetian_HadCM_new_2PIC_model.columns if '_D47_SE' in col]
print("D47 values for all HadCM model 2x preindustrial pCO2 outcomes:\n", Lutetian_HadCM_new_2PIC_model[D47_HadCM_new_2PIC_columns].head())
print("Calibration standard errors for all HadCM model 2x preindustrial pCO2 outcomes:\n", Lutetian_HadCM_new_2PIC_model[D47_se_HadCM_new_2PIC_columns].head())
D47 values for all HadCM model 2x preindustrial pCO2 outcomes:
ja_SAT_D47 fb_SAT_D47 mr_SAT_D47 ar_SAT_D47 my_SAT_D47 jn_SAT_D47 \
0 0.635263 0.636188 0.633511 0.628476 0.616460 0.599641
1 0.642249 0.643730 0.640365 0.634105 0.619013 0.599103
2 0.642214 0.644917 0.642775 0.637497 0.623075 0.602602
3 0.624396 0.625315 0.622902 0.619219 0.609535 0.593964
4 0.650031 0.646115 0.635630 0.626910 0.611551 0.596251
jl_SAT_D47 ag_SAT_D47 sp_SAT_D47 ot_SAT_D47 ... mr_SST_D47 \
0 0.586221 0.583641 0.591666 0.605627 ... 0.611563
1 0.587329 0.585721 0.594725 0.610488 ... 0.610890
2 0.589389 0.587108 0.595950 0.610777 ... 0.618880
3 0.583649 0.581971 0.587516 0.598996 ... 0.611383
4 0.589929 0.589576 0.598179 0.614516 ... 0.614333
ar_SST_D47 my_SST_D47 jn_SST_D47 jl_SST_D47 ag_SST_D47 sp_SST_D47 \
0 0.609661 0.603153 0.591553 0.584571 0.582125 0.583000
1 0.609423 0.603150 0.591251 0.584502 0.582306 0.583049
2 0.615656 0.606011 0.592279 0.585107 0.582909 0.584535
3 0.610592 0.605196 0.592472 0.582463 0.579974 0.582705
4 0.612994 0.605889 0.591694 0.582842 0.580932 0.583752
ot_SST_D47 nv_SST_D47 dc_SST_D47
0 0.590649 0.600020 0.606596
1 0.590448 0.599235 0.605800
2 0.592975 0.602354 0.610318
3 0.590459 0.598792 0.604624
4 0.591868 0.601060 0.607322
[5 rows x 24 columns]
Calibration standard errors for all HadCM model 2x preindustrial pCO2 outcomes:
ja_SAT_D47_SE fb_SAT_D47_SE mr_SAT_D47_SE ar_SAT_D47_SE my_SAT_D47_SE \
0 0.001235 0.001241 0.001223 0.001192 0.001130
1 0.001283 0.001293 0.001269 0.001227 0.001142
2 0.001282 0.001302 0.001286 0.001249 0.001162
3 0.001169 0.001174 0.001161 0.001143 0.001101
4 0.001341 0.001311 0.001237 0.001183 0.001108
jn_SAT_D47_SE jl_SAT_D47_SE ag_SAT_D47_SE sp_SAT_D47_SE ot_SAT_D47_SE \
0 0.001069 0.001045 0.001043 0.001052 0.001087
1 0.001068 0.001046 0.001044 0.001058 0.001104
2 0.001077 0.001049 0.001046 0.001060 0.001105
3 0.001056 0.001043 0.001042 0.001046 0.001067
4 0.001061 0.001049 0.001049 0.001065 0.001121
... mr_SST_D47_SE ar_SST_D47_SE my_SST_D47_SE jn_SST_D47_SE \
0 ... 0.001109 0.001101 0.001079 0.001052
1 ... 0.001106 0.001100 0.001079 0.001051
2 ... 0.001141 0.001126 0.001088 0.001053
3 ... 0.001108 0.001105 0.001085 0.001053
4 ... 0.001120 0.001114 0.001088 0.001052
jl_SST_D47_SE ag_SST_D47_SE sp_SST_D47_SE ot_SST_D47_SE nv_SST_D47_SE \
0 0.001044 0.001042 0.001042 0.001050 0.001070
1 0.001043 0.001042 0.001042 0.001050 0.001068
2 0.001044 0.001042 0.001043 0.001054 0.001076
3 0.001042 0.001041 0.001042 0.001050 0.001067
4 0.001042 0.001041 0.001043 0.001052 0.001073
dc_SST_D47_SE
0 0.001090
1 0.001087
2 0.001104
3 0.001083
4 0.001093
[5 rows x 24 columns]
For new HadCM model with 1056 ppm pCO2¶
In [25]:
# Convert temperature data for the HadCM model with 1056 ppm CO2
# Identify the SAT and SST columns
SAT_HadCM_new_1056ppm_columns = [col for col in Lutetian_HadCM_new_1056ppm_model.columns if col.endswith('_SAT')]
SST_HadCM_new_1056ppm_columns = [col for col in Lutetian_HadCM_new_1056ppm_model.columns if col.endswith('_SST')]
# Apply the conversion function to the SAT columns and add new columns for D47 and D47_SE
for col in SAT_HadCM_new_1056ppm_columns:
base_col_name = col.replace('_SAT', '') # Remove the '_SAT' suffix from the column name
Lutetian_HadCM_new_1056ppm_model[f'{base_col_name}_SAT_D47'], Lutetian_HadCM_new_1056ppm_model[f'{base_col_name}_SAT_D47_SE'] = zip(*Lutetian_HadCM_new_1056ppm_model[col].apply(
lambda x: D47c.OGLS23.T47(T = x) if not pd.isna(x) else (np.nan, np.nan)
)) # Use zip() to unpack the tuple returned by the apply() method and apply the T47()-function to each value in the column
for col in SST_HadCM_new_1056ppm_columns:
base_col_name = col.replace('_SST', '') # Remove the '_SST' suffix from the column name
Lutetian_HadCM_new_1056ppm_model[f'{base_col_name}_SST_D47'], Lutetian_HadCM_new_1056ppm_model[f'{base_col_name}_SST_D47_SE'] = zip(*Lutetian_HadCM_new_1056ppm_model[col].apply(
lambda x: D47c.OGLS23.T47(T = x) if not pd.isna(x) else (np.nan, np.nan)
)) # Use zip() to unpack the tuple returned by the apply() method and apply the T47()-function to each value in the column
# Display the combined data with D47 and D47_SE columns
D47_HadCM_new_1056ppm_columns = [col for col in Lutetian_HadCM_new_1056ppm_model.columns if col.endswith('_D47')]
D47_se_HadCM_new_1056ppm_columns = [col for col in Lutetian_HadCM_new_1056ppm_model.columns if '_D47_SE' in col]
print("D47 values for all HadCM model 1056 ppm pCO2 outcomes:\n", Lutetian_HadCM_new_1056ppm_model[D47_HadCM_new_1056ppm_columns].head())
print("Calibration standard errors for all HadCM model 1056 ppm pCO2 outcomes:\n", Lutetian_HadCM_new_1056ppm_model[D47_se_HadCM_new_1056ppm_columns].head())
D47 values for all HadCM model 1056 ppm pCO2 outcomes:
ja_SAT_D47 fb_SAT_D47 mr_SAT_D47 ar_SAT_D47 my_SAT_D47 jn_SAT_D47 \
0 0.625999 0.626866 0.625237 0.619942 0.608866 0.592780
1 0.631948 0.632783 0.631225 0.624299 0.610803 0.591568
2 0.631501 0.633310 0.633035 0.627377 0.614579 0.594306
3 0.615905 0.616517 0.615368 0.611138 0.602291 0.587788
4 0.638832 0.633538 0.627128 0.616879 0.603802 0.588733
jl_SAT_D47 ag_SAT_D47 sp_SAT_D47 ot_SAT_D47 ... mr_SST_D47 \
0 0.579672 0.576946 0.584411 0.597488 ... 0.605123
1 0.579762 0.578541 0.586737 0.601736 ... 0.604587
2 0.581854 0.580169 0.588095 0.601666 ... 0.611901
3 0.577532 0.575583 0.580775 0.591800 ... 0.604890
4 0.580942 0.581502 0.589338 0.605672 ... 0.607587
ar_SST_D47 my_SST_D47 jn_SST_D47 jl_SST_D47 ag_SST_D47 sp_SST_D47 \
0 0.603131 0.597247 0.587153 0.580623 0.577211 0.577595
1 0.603123 0.597526 0.586721 0.579954 0.576934 0.577456
2 0.608641 0.600078 0.587311 0.580162 0.577275 0.578731
3 0.604036 0.598871 0.587694 0.578456 0.574712 0.577089
4 0.606307 0.599742 0.587023 0.578345 0.575325 0.577753
ot_SST_D47 nv_SST_D47 dc_SST_D47
0 0.584750 0.594385 0.600574
1 0.584307 0.593765 0.599964
2 0.586423 0.596758 0.604276
3 0.584295 0.592687 0.598288
4 0.585403 0.595043 0.600976
[5 rows x 24 columns]
Calibration standard errors for all HadCM model 1056 ppm pCO2 outcomes:
ja_SAT_D47_SE fb_SAT_D47_SE mr_SAT_D47_SE ar_SAT_D47_SE my_SAT_D47_SE \
0 0.001178 0.001183 0.001174 0.001146 0.001098
1 0.001213 0.001219 0.001209 0.001169 0.001105
2 0.001211 0.001222 0.001220 0.001186 0.001121
3 0.001127 0.001130 0.001125 0.001107 0.001076
4 0.001259 0.001223 0.001185 0.001132 0.001081
jn_SAT_D47_SE jl_SAT_D47_SE ag_SAT_D47_SE sp_SAT_D47_SE ot_SAT_D47_SE \
0 0.001054 0.001041 0.001041 0.001043 0.001064
1 0.001052 0.001041 0.001041 0.001045 0.001075
2 0.001057 0.001042 0.001041 0.001047 0.001074
3 0.001047 0.001041 0.001041 0.001041 0.001052
4 0.001048 0.001041 0.001042 0.001049 0.001087
... mr_SST_D47_SE ar_SST_D47_SE my_SST_D47_SE jn_SST_D47_SE \
0 ... 0.001085 0.001079 0.001063 0.001046
1 ... 0.001083 0.001079 0.001064 0.001045
2 ... 0.001110 0.001097 0.001070 0.001046
3 ... 0.001084 0.001082 0.001067 0.001047
4 ... 0.001093 0.001089 0.001069 0.001046
jl_SST_D47_SE ag_SST_D47_SE sp_SST_D47_SE ot_SST_D47_SE nv_SST_D47_SE \
0 0.001041 0.001041 0.001041 0.001044 0.001057
1 0.001041 0.001041 0.001041 0.001043 0.001056
2 0.001041 0.001041 0.001041 0.001045 0.001062
3 0.001041 0.001042 0.001041 0.001043 0.001054
4 0.001041 0.001041 0.001041 0.001044 0.001058
dc_SST_D47_SE
0 0.001071
1 0.001070
2 0.001082
3 0.001066
4 0.001073
[5 rows x 24 columns]
For old HadCM model with 2x perindustrial pCO2¶
In [26]:
# Convert temperature data for the old HadCM model with 2x pre-industrial CO2
# Identify the SAT and SST columns
SAT_HadCM_old_2PIC_columns = [col for col in Lutetian_HadCM_old_2PIC_model.columns if col.endswith('_SAT')]
SST_HadCM_old_2PIC_columns = [col for col in Lutetian_HadCM_old_2PIC_model.columns if col.endswith('_SST')]
# Apply the conversion function to the SAT columns and add new columns for D47 and D47_SE
for col in SAT_HadCM_old_2PIC_columns:
base_col_name = col.replace('_SAT', '') # Remove the '_SAT' suffix from the column name
Lutetian_HadCM_old_2PIC_model[f'{base_col_name}_SAT_D47'], Lutetian_HadCM_old_2PIC_model[f'{base_col_name}_SAT_D47_SE'] = zip(*Lutetian_HadCM_old_2PIC_model[col].apply(
lambda x: D47c.OGLS23.T47(T = x) if not pd.isna(x) else (np.nan, np.nan)
)) # Use zip() to unpack the tuple returned by the apply() method and apply the T47()-function to each value in the column
for col in SST_HadCM_old_2PIC_columns:
base_col_name = col.replace('_SST', '') # Remove the '_SST' suffix from the column name
Lutetian_HadCM_old_2PIC_model[f'{base_col_name}_SST_D47'], Lutetian_HadCM_old_2PIC_model[f'{base_col_name}_SST_D47_SE'] = zip(*Lutetian_HadCM_old_2PIC_model[col].apply(
lambda x: D47c.OGLS23.T47(T = x) if not pd.isna(x) else (np.nan, np.nan)
)) # Use zip() to unpack the tuple returned by the apply() method and apply the T47()-function to each value in the column
# Display the combined data with D47 and D47_SE columns
D47_HadCM_old_2PIC_columns = [col for col in Lutetian_HadCM_old_2PIC_model.columns if col.endswith('_D47')]
D47_se_HadCM_old_2PIC_columns = [col for col in Lutetian_HadCM_old_2PIC_model.columns if '_D47_SE' in col]
print("D47 values for all old HadCM model 2x preindustrial pCO2 outcomes:\n", Lutetian_HadCM_old_2PIC_model[D47_HadCM_old_2PIC_columns].head())
print("Calibration standard errors for all old HadCM model 2x preindustrial pCO2 outcomes:\n", Lutetian_HadCM_old_2PIC_model[D47_se_HadCM_old_2PIC_columns].head())
D47 values for all old HadCM model 2x preindustrial pCO2 outcomes:
ja_SAT_D47 fb_SAT_D47 mr_SAT_D47 ar_SAT_D47 my_SAT_D47 jn_SAT_D47 \
0 0.621479 0.621749 0.619999 0.615386 0.606099 0.594473
1 0.626878 0.626964 0.624847 0.619754 0.608017 0.593061
2 0.627793 0.629021 0.627793 0.622599 0.610761 0.594346
3 0.612452 0.613220 0.612154 0.608198 0.599813 0.588684
4 0.642211 0.635149 0.624440 0.612316 0.598682 0.582807
jl_SAT_D47 ag_SAT_D47 sp_SAT_D47 ot_SAT_D47 ... mr_SST_D47 \
0 0.583127 0.576368 0.580028 0.592956 ... 0.604433
1 0.581541 0.575316 0.580263 0.595627 ... 0.604986
2 0.581769 0.576907 0.582607 0.596563 ... 0.607415
3 0.579127 0.574798 0.577224 0.587470 ... 0.606422
4 0.575847 0.575000 0.585403 0.603424 ... 0.608445
ar_SST_D47 my_SST_D47 jn_SST_D47 jl_SST_D47 ag_SST_D47 sp_SST_D47 \
0 0.601636 0.594606 0.584886 0.579352 0.576142 0.575630
1 0.602297 0.594689 0.583945 0.578157 0.575023 0.574856
2 0.603910 0.594881 0.583445 0.578165 0.575373 0.575115
3 0.603856 0.596232 0.585046 0.577843 0.574394 0.575516
4 0.605995 0.598629 0.587366 0.579447 0.575822 0.576716
ot_SST_D47 nv_SST_D47 dc_SST_D47
0 0.581670 0.590809 0.598345
1 0.581191 0.590222 0.598174
2 0.582326 0.591776 0.600193
3 0.583441 0.593301 0.600655
4 0.585471 0.595260 0.602927
[5 rows x 24 columns]
Calibration standard errors for all old HadCM model 2x preindustrial pCO2 outcomes:
ja_SAT_D47_SE fb_SAT_D47_SE mr_SAT_D47_SE ar_SAT_D47_SE my_SAT_D47_SE \
0 0.001154 0.001155 0.001146 0.001125 0.001088
1 0.001183 0.001184 0.001172 0.001145 0.001095
2 0.001188 0.001196 0.001188 0.001160 0.001105
3 0.001112 0.001115 0.001111 0.001096 0.001069
4 0.001282 0.001234 0.001170 0.001112 0.001067
jn_SAT_D47_SE jl_SAT_D47_SE ag_SAT_D47_SE sp_SAT_D47_SE ot_SAT_D47_SE \
0 0.001057 0.001043 0.001041 0.001041 0.001054
1 0.001054 0.001042 0.001041 0.001041 0.001059
2 0.001057 0.001042 0.001041 0.001042 0.001062
3 0.001048 0.001041 0.001042 0.001041 0.001046
4 0.001042 0.001041 0.001041 0.001044 0.001080
... mr_SST_D47_SE ar_SST_D47_SE my_SST_D47_SE jn_SST_D47_SE \
0 ... 0.001083 0.001074 0.001057 0.001044
1 ... 0.001085 0.001076 0.001058 0.001043
2 ... 0.001093 0.001081 0.001058 0.001043
3 ... 0.001089 0.001081 0.001061 0.001044
4 ... 0.001097 0.001088 0.001066 0.001046
jl_SST_D47_SE ag_SST_D47_SE sp_SST_D47_SE ot_SST_D47_SE nv_SST_D47_SE \
0 0.001041 0.001041 0.001041 0.001042 0.001051
1 0.001041 0.001041 0.001042 0.001042 0.001050
2 0.001041 0.001041 0.001041 0.001042 0.001052
3 0.001041 0.001042 0.001041 0.001043 0.001055
4 0.001041 0.001041 0.001041 0.001044 0.001059
dc_SST_D47_SE
0 0.001066
1 0.001065
2 0.001070
3 0.001072
4 0.001078
[5 rows x 24 columns]
For old HadCM model with 4x perindustrial pCO2¶
In [27]:
# Convert temperature data for the old HadCM model with 4x pre-industrial CO2
# Identify the SAT and SST columns
SAT_HadCM_old_4PIC_columns = [col for col in Lutetian_HadCM_old_4PIC_model.columns if col.endswith('_SAT')]
SST_HadCM_old_4PIC_columns = [col for col in Lutetian_HadCM_old_4PIC_model.columns if col.endswith('_SST')]
# Apply the conversion function to the SAT columns and add new columns for D47 and D47_SE
for col in SAT_HadCM_old_4PIC_columns:
base_col_name = col.replace('_SAT', '') # Remove the '_SAT' suffix from the column name
Lutetian_HadCM_old_4PIC_model[f'{base_col_name}_SAT_D47'], Lutetian_HadCM_old_4PIC_model[f'{base_col_name}_SAT_D47_SE'] = zip(*Lutetian_HadCM_old_4PIC_model[col].apply(
lambda x: D47c.OGLS23.T47(T = x) if not pd.isna(x) else (np.nan, np.nan)
)) # Use zip() to unpack the tuple returned by the apply() method and apply the T47()-function to each value in the column
for col in SST_HadCM_old_4PIC_columns:
base_col_name = col.replace('_SST', '') # Remove the '_SST' suffix from the column name
Lutetian_HadCM_old_4PIC_model[f'{base_col_name}_SST_D47'], Lutetian_HadCM_old_4PIC_model[f'{base_col_name}_SST_D47_SE'] = zip(*Lutetian_HadCM_old_4PIC_model[col].apply(
lambda x: D47c.OGLS23.T47(T = x) if not pd.isna(x) else (np.nan, np.nan)
)) # Use zip() to unpack the tuple returned by the apply() method and apply the T47()-function to each value in the column
# Display the combined data with D47 and D47_SE columns
D47_HadCM_old_4PIC_columns = [col for col in Lutetian_HadCM_old_4PIC_model.columns if col.endswith('_D47')]
D47_se_HadCM_old_4PIC_columns = [col for col in Lutetian_HadCM_old_4PIC_model.columns if '_D47_SE' in col]
print("D47 values for all old HadCM model 4x preindustrial pCO2 outcomes:\n", Lutetian_HadCM_old_4PIC_model[D47_HadCM_old_4PIC_columns].head())
print("Calibration standard errors for all old HadCM model 4x preindustrial pCO2 outcomes:\n", Lutetian_HadCM_old_4PIC_model[D47_se_HadCM_old_4PIC_columns].head())
D47 values for all old HadCM model 4x preindustrial pCO2 outcomes:
ja_SAT_D47 fb_SAT_D47 mr_SAT_D47 ar_SAT_D47 my_SAT_D47 jn_SAT_D47 \
0 0.621479 0.621749 0.619999 0.615386 0.606099 0.594473
1 0.626878 0.626964 0.624847 0.619754 0.608017 0.593061
2 0.627793 0.629021 0.627793 0.622599 0.610761 0.594346
3 0.612452 0.613220 0.612154 0.608198 0.599813 0.588684
4 0.642211 0.635149 0.624440 0.612316 0.598682 0.582807
jl_SAT_D47 ag_SAT_D47 sp_SAT_D47 ot_SAT_D47 ... mr_SST_D47 \
0 0.583127 0.576368 0.580028 0.592956 ... 0.604433
1 0.581541 0.575316 0.580263 0.595627 ... 0.604986
2 0.581769 0.576907 0.582607 0.596563 ... 0.607415
3 0.579127 0.574798 0.577224 0.587470 ... 0.606422
4 0.575847 0.575000 0.585403 0.603424 ... 0.608445
ar_SST_D47 my_SST_D47 jn_SST_D47 jl_SST_D47 ag_SST_D47 sp_SST_D47 \
0 0.601636 0.594606 0.584886 0.579352 0.576142 0.575630
1 0.602297 0.594689 0.583945 0.578157 0.575023 0.574856
2 0.603910 0.594881 0.583445 0.578165 0.575373 0.575115
3 0.603856 0.596232 0.585046 0.577843 0.574394 0.575516
4 0.605995 0.598629 0.587366 0.579447 0.575822 0.576716
ot_SST_D47 nv_SST_D47 dc_SST_D47
0 0.581670 0.590809 0.598345
1 0.581191 0.590222 0.598174
2 0.582326 0.591776 0.600193
3 0.583441 0.593301 0.600655
4 0.585471 0.595260 0.602927
[5 rows x 24 columns]
Calibration standard errors for all old HadCM model 4x preindustrial pCO2 outcomes:
ja_SAT_D47_SE fb_SAT_D47_SE mr_SAT_D47_SE ar_SAT_D47_SE my_SAT_D47_SE \
0 0.001154 0.001155 0.001146 0.001125 0.001088
1 0.001183 0.001184 0.001172 0.001145 0.001095
2 0.001188 0.001196 0.001188 0.001160 0.001105
3 0.001112 0.001115 0.001111 0.001096 0.001069
4 0.001282 0.001234 0.001170 0.001112 0.001067
jn_SAT_D47_SE jl_SAT_D47_SE ag_SAT_D47_SE sp_SAT_D47_SE ot_SAT_D47_SE \
0 0.001057 0.001043 0.001041 0.001041 0.001054
1 0.001054 0.001042 0.001041 0.001041 0.001059
2 0.001057 0.001042 0.001041 0.001042 0.001062
3 0.001048 0.001041 0.001042 0.001041 0.001046
4 0.001042 0.001041 0.001041 0.001044 0.001080
... mr_SST_D47_SE ar_SST_D47_SE my_SST_D47_SE jn_SST_D47_SE \
0 ... 0.001083 0.001074 0.001057 0.001044
1 ... 0.001085 0.001076 0.001058 0.001043
2 ... 0.001093 0.001081 0.001058 0.001043
3 ... 0.001089 0.001081 0.001061 0.001044
4 ... 0.001097 0.001088 0.001066 0.001046
jl_SST_D47_SE ag_SST_D47_SE sp_SST_D47_SE ot_SST_D47_SE nv_SST_D47_SE \
0 0.001041 0.001041 0.001041 0.001042 0.001051
1 0.001041 0.001041 0.001042 0.001042 0.001050
2 0.001041 0.001041 0.001041 0.001042 0.001052
3 0.001041 0.001042 0.001041 0.001043 0.001055
4 0.001041 0.001041 0.001041 0.001044 0.001059
dc_SST_D47_SE
0 0.001066
1 0.001065
2 0.001070
3 0.001072
4 0.001078
[5 rows x 24 columns]
Estimate seawater oxygen isotope value from salinity based on modern North Sea d18Ow-salinity relationship by Harwood et al. (2007)¶
For CESM with 4x perindustrial pCO2¶
In [28]:
# Apply the d18Ow-SSS function from Harwood et al. (2007) to all SSS columns
# First for the CESM model with 4x pre-industrial CO2
# Identify the SSS columns
SSS_CESM_4PIC_columns = [col for col in Lutetian_CESM_4PIC_model.columns if col.endswith('_SSS')]
# Apply the conversion function to the SSS columns and add new columns for d18Ow and d18Ow_SE
for col in SSS_CESM_4PIC_columns:
base_col_name = col.replace('_SSS', '') # Remove the '_SSS' suffix from the column name
Lutetian_CESM_4PIC_model[f'{base_col_name}_SSS_d18Ow'] = Lutetian_CESM_4PIC_model[col].apply(
lambda x: -9.300 + 0.274 * x if not pd.isna(x) else np.nan # Calculate d18Ow
)
# Display the combined data with d18Ow and d18Ow_SE columns
d18Ow_CESM_4PIC_columns = [col for col in Lutetian_CESM_4PIC_model.columns if col.endswith('_d18Ow')]
print("d18Ow values for all model outcomes:\n", Lutetian_CESM_4PIC_model[d18Ow_CESM_4PIC_columns].head())
d18Ow values for all model outcomes:
ja_SSS_d18Ow fb_SSS_d18Ow mr_SSS_d18Ow ar_SSS_d18Ow my_SSS_d18Ow \
0 0.412163 0.417397 0.416426 0.420510 0.427636
1 0.412551 0.419215 0.420105 0.424757 0.431978
2 0.391470 0.397124 0.397364 0.401573 0.409009
3 -1.716298 -1.696593 -1.699113 -1.718610 -1.746921
4 -1.724499 -1.705170 -1.711377 -1.735129 -1.771551
jn_SSS_d18Ow jl_SSS_d18Ow ag_SSS_d18Ow sp_SSS_d18Ow ot_SSS_d18Ow \
0 0.433800 0.432326 0.418661 0.386762 0.361828
1 0.436819 0.435099 0.426873 0.402075 0.378333
2 0.412444 0.409529 0.403192 0.382842 0.365661
3 -1.771086 -1.798713 -1.820124 -1.836465 -1.833743
4 -1.802794 -1.832529 -1.854027 -1.869227 -1.862037
nv_SSS_d18Ow dc_SSS_d18Ow
0 0.371852 0.395830
1 0.379386 0.397893
2 0.365822 0.380555
3 -1.797647 -1.748480
4 -1.814293 -1.760033
For CESM with 2x perindustrial pCO2¶
In [29]:
# Calculate d18Ow for the CESM model with 2x pre-industrial CO2
# Identify the SSS columns
SSS_CESM_2PIC_columns = [col for col in Lutetian_CESM_2PIC_model.columns if col.endswith('_SSS')]
# Apply the conversion function to the SSS columns and add new columns for d18Ow and d18Ow_SE
for col in SSS_CESM_2PIC_columns:
base_col_name = col.replace('_SSS', '') # Remove the '_SSS' suffix from the column name
Lutetian_CESM_2PIC_model[f'{base_col_name}_SSS_d18Ow'] = Lutetian_CESM_2PIC_model[col].apply(
lambda x: -9.300 + 0.274 * x if not pd.isna(x) else np.nan # Calculate d18Ow
)
# Display the combined data with d18Ow and d18Ow_SE columns
d18Ow_CESM_2PIC_columns = [col for col in Lutetian_CESM_2PIC_model.columns if col.endswith('_d18Ow')]
print("d18Ow values for all model outcomes:\n", Lutetian_CESM_2PIC_model[d18Ow_CESM_2PIC_columns].head())
d18Ow values for all model outcomes:
ja_SSS_d18Ow fb_SSS_d18Ow mr_SSS_d18Ow ar_SSS_d18Ow my_SSS_d18Ow \
0 0.457617 0.449562 0.442842 0.440457 0.448478
1 0.455972 0.451012 0.445746 0.443246 0.448766
2 0.433992 0.429306 0.423751 0.420202 0.423995
3 -1.600125 -1.587918 -1.593103 -1.623087 -1.663342
4 -1.604723 -1.595348 -1.603947 -1.641113 -1.687715
jn_SSS_d18Ow jl_SSS_d18Ow ag_SSS_d18Ow sp_SSS_d18Ow ot_SSS_d18Ow \
0 0.455517 0.457858 0.451676 0.438730 0.432616
1 0.453875 0.455338 0.453152 0.446492 0.440568
2 0.426841 0.425764 0.424374 0.423545 0.422326
3 -1.691195 -1.716381 -1.737248 -1.747069 -1.739627
4 -1.720774 -1.747673 -1.767869 -1.776518 -1.764211
nv_SSS_d18Ow dc_SSS_d18Ow
0 0.444299 0.456633
1 0.446245 0.454761
2 0.428876 0.435168
3 -1.698605 -1.638065
4 -1.709789 -1.641279
For new HadCM model with 1x perindustrial pCO2¶
In [30]:
# Calculate d18Ow for the new HadCM model with 2x pre-industrial CO2
# Identify the SSS columns
SSS_HadCM_new_1PIC_columns = [col for col in Lutetian_HadCM_new_1PIC_model.columns if col.endswith('_SSS')]
# Apply the conversion function to the SSS columns and add new columns for d18Ow and d18Ow_SE
for col in SSS_HadCM_new_1PIC_columns:
base_col_name = col.replace('_SSS', '') # Remove the '_SSS' suffix from the column name
Lutetian_HadCM_new_1PIC_model[f'{base_col_name}_SSS_d18Ow'] = Lutetian_HadCM_new_1PIC_model[col].apply(
lambda x: -9.300 + 0.274 * x if not pd.isna(x) else np.nan # Calculate d18Ow
)
# Display the combined data with d18Ow and d18Ow_SE columns
d18Ow_HadCM_new_1PIC_columns = [col for col in Lutetian_HadCM_new_1PIC_model.columns if col.endswith('_d18Ow')]
print("d18Ow values for all model outcomes:\n", Lutetian_HadCM_new_1PIC_model[d18Ow_HadCM_new_1PIC_columns].head())
d18Ow values for all model outcomes:
ja_SSS_d18Ow fb_SSS_d18Ow mr_SSS_d18Ow ar_SSS_d18Ow my_SSS_d18Ow \
0 0.728492 0.723816 0.722658 0.723479 0.723571
1 0.725648 0.724492 0.725863 0.728494 0.731327
2 0.678770 0.672299 0.675349 0.681626 0.690663
3 0.732131 0.730294 0.726656 0.725570 0.721657
4 0.713698 0.714482 0.714582 0.716600 0.719887
jn_SSS_d18Ow jl_SSS_d18Ow ag_SSS_d18Ow sp_SSS_d18Ow ot_SSS_d18Ow \
0 0.718046 0.707071 0.700301 0.712572 0.730776
1 0.732760 0.724390 0.719080 0.727738 0.737476
2 0.698161 0.693189 0.688407 0.698954 0.706362
3 0.710901 0.691207 0.675716 0.688672 0.708663
4 0.715040 0.706389 0.699770 0.708793 0.721798
nv_SSS_d18Ow dc_SSS_d18Ow
0 0.738091 0.735785
1 0.738508 0.733766
2 0.701069 0.690490
3 0.721718 0.728676
4 0.716220 0.713410
For new HadCM model with 2x perindustrial pCO2¶
In [31]:
# Calculate d18Ow for the new HadCM model with 2x pre-industrial CO2
# Identify the SSS columns
SSS_HadCM_new_2PIC_columns = [col for col in Lutetian_HadCM_new_2PIC_model.columns if col.endswith('_SSS')]
# Apply the conversion function to the SSS columns and add new columns for d18Ow and d18Ow_SE
for col in SSS_HadCM_new_2PIC_columns:
base_col_name = col.replace('_SSS', '') # Remove the '_SSS' suffix from the column name
Lutetian_HadCM_new_2PIC_model[f'{base_col_name}_SSS_d18Ow'] = Lutetian_HadCM_new_2PIC_model[col].apply(
lambda x: -9.300 + 0.274 * x if not pd.isna(x) else np.nan # Calculate d18Ow
)
# Display the combined data with d18Ow and d18Ow_SE columns
d18Ow_HadCM_new_2PIC_columns = [col for col in Lutetian_HadCM_new_2PIC_model.columns if col.endswith('_d18Ow')]
print("d18Ow values for all model outcomes:\n", Lutetian_HadCM_new_2PIC_model[d18Ow_HadCM_new_2PIC_columns].head())
d18Ow values for all model outcomes:
ja_SSS_d18Ow fb_SSS_d18Ow mr_SSS_d18Ow ar_SSS_d18Ow my_SSS_d18Ow \
0 0.811437 0.805487 0.805250 0.807841 0.803697
1 0.806881 0.804756 0.807213 0.810979 0.811752
2 0.758579 0.751175 0.754590 0.762000 0.771146
3 0.815456 0.812143 0.808163 0.807469 0.799893
4 0.794913 0.794419 0.794913 0.798267 0.798405
jn_SSS_d18Ow jl_SSS_d18Ow ag_SSS_d18Ow sp_SSS_d18Ow ot_SSS_d18Ow \
0 0.800994 0.796440 0.790733 0.808524 0.823438
1 0.816399 0.810916 0.804832 0.819014 0.826845
2 0.779537 0.775815 0.773348 0.787377 0.791992
3 0.791814 0.783627 0.763053 0.779218 0.797621
4 0.793836 0.788603 0.779419 0.793240 0.806758
nv_SSS_d18Ow dc_SSS_d18Ow
0 0.827773 0.821396
1 0.824124 0.815710
2 0.783353 0.771397
3 0.808397 0.813004
4 0.800027 0.795366
For new HadCM model with 1056 ppm pCO2¶
In [32]:
# Calculate d18Ow for the new HadCM model with 1056 ppm CO2
# Identify the SSS columns
SSS_HadCM_new_1056ppm_columns = [col for col in Lutetian_HadCM_new_1056ppm_model.columns if col.endswith('_SSS')]
# Apply the conversion function to the SSS columns and add new columns for d18Ow and d18Ow_SE
for col in SSS_HadCM_new_1056ppm_columns:
base_col_name = col.replace('_SSS', '') # Remove the '_SSS' suffix from the column name
Lutetian_HadCM_new_1056ppm_model[f'{base_col_name}_SSS_d18Ow'] = Lutetian_HadCM_new_1056ppm_model[col].apply(
lambda x: -9.300 + 0.274 * x if not pd.isna(x) else np.nan # Calculate d18Ow
)
# Display the combined data with d18Ow and d18Ow_SE columns
d18Ow_HadCM_new_1056ppm_columns = [col for col in Lutetian_HadCM_new_1056ppm_model.columns if col.endswith('_d18Ow')]
print("d18Ow values for all model outcomes:\n", Lutetian_HadCM_new_1056ppm_model[d18Ow_HadCM_new_1056ppm_columns].head())
d18Ow values for all model outcomes:
ja_SSS_d18Ow fb_SSS_d18Ow mr_SSS_d18Ow ar_SSS_d18Ow my_SSS_d18Ow \
0 0.873898 0.867618 0.867569 0.871600 0.873578
1 0.865885 0.864033 0.865524 0.870754 0.876423
2 0.812660 0.806048 0.809213 0.819473 0.832309
3 0.883941 0.876824 0.872641 0.872904 0.867391
4 0.857655 0.855579 0.854971 0.859815 0.863475
jn_SSS_d18Ow jl_SSS_d18Ow ag_SSS_d18Ow sp_SSS_d18Ow ot_SSS_d18Ow \
0 0.872901 0.880796 0.893093 0.909543 0.908607
1 0.883397 0.888450 0.895552 0.909154 0.901718
2 0.844635 0.848587 0.854068 0.866653 0.857756
3 0.858121 0.863630 0.867814 0.878142 0.884862
4 0.859093 0.862812 0.870127 0.882386 0.883423
nv_SSS_d18Ow dc_SSS_d18Ow
0 0.901013 0.887231
1 0.888703 0.875178
2 0.841337 0.826700
3 0.888496 0.885850
4 0.868421 0.859741
For old HadCM model with 2x perindustrial pCO2¶
In [33]:
# Calculate d18Ow for the old HadCM model with 2x pre-industrial CO2
# Identify the SSS columns
SSS_HadCM_old_2PIC_columns = [col for col in Lutetian_HadCM_old_2PIC_model.columns if col.endswith('_SSS')]
# Apply the conversion function to the SSS columns and add new columns for d18Ow and d18Ow_SE
for col in SSS_HadCM_old_2PIC_columns:
base_col_name = col.replace('_SSS', '') # Remove the '_SSS' suffix from the column name
Lutetian_HadCM_old_2PIC_model[f'{base_col_name}_SSS_d18Ow'] = Lutetian_HadCM_old_2PIC_model[col].apply(
lambda x: -9.300 + 0.274 * x if not pd.isna(x) else np.nan # Calculate d18Ow
)
# Display the combined data with d18Ow and d18Ow_SE columns
d18Ow_HadCM_old_2PIC_columns = [col for col in Lutetian_HadCM_old_2PIC_model.columns if col.endswith('_d18Ow')]
print("d18Ow values for all model outcomes:\n", Lutetian_HadCM_old_2PIC_model[d18Ow_HadCM_old_2PIC_columns].head())
d18Ow values for all model outcomes:
ja_SSS_d18Ow fb_SSS_d18Ow mr_SSS_d18Ow ar_SSS_d18Ow my_SSS_d18Ow \
0 2.730385 2.744889 2.747529 2.741694 2.738172
1 2.795991 2.802639 2.805744 2.804372 2.808415
2 2.837809 2.840615 2.840784 2.840007 2.851089
3 2.777538 2.785695 2.791531 2.788105 2.786381
4 2.809492 2.814421 2.818105 2.819479 2.818072
jn_SSS_d18Ow jl_SSS_d18Ow ag_SSS_d18Ow sp_SSS_d18Ow ot_SSS_d18Ow \
0 2.750210 2.759200 2.772942 2.769145 2.745299
1 2.828405 2.840431 2.852451 2.850035 2.827458
2 2.875549 2.889367 2.895949 2.892115 2.864288
3 2.799461 2.820661 2.842595 2.836395 2.806944
4 2.827237 2.844929 2.866786 2.863590 2.838464
nv_SSS_d18Ow dc_SSS_d18Ow
0 2.729710 2.726179
1 2.811291 2.800433
2 2.849760 2.841525
3 2.785955 2.777641
4 2.820463 2.812720
For old HadCM model with 4x perindustrial pCO2¶
In [34]:
# Calculate d18Ow for the old HadCM model with 4x pre-industrial CO2
# Identify the SSS columns
SSS_HadCM_old_4PIC_columns = [col for col in Lutetian_HadCM_old_4PIC_model.columns if col.endswith('_SSS')]
# Apply the conversion function to the SSS columns and add new columns for d18Ow and d18Ow_SE
for col in SSS_HadCM_old_4PIC_columns:
base_col_name = col.replace('_SSS', '') # Remove the '_SSS' suffix from the column name
Lutetian_HadCM_old_4PIC_model[f'{base_col_name}_SSS_d18Ow'] = Lutetian_HadCM_old_4PIC_model[col].apply(
lambda x: -9.300 + 0.274 * x if not pd.isna(x) else np.nan # Calculate d18Ow
)
# Display the combined data with d18Ow and d18Ow_SE columns
d18Ow_HadCM_old_4PIC_columns = [col for col in Lutetian_HadCM_old_4PIC_model.columns if col.endswith('_d18Ow')]
print("d18Ow values for all model outcomes:\n", Lutetian_HadCM_old_4PIC_model[d18Ow_HadCM_old_4PIC_columns].head())
d18Ow values for all model outcomes:
ja_SSS_d18Ow fb_SSS_d18Ow mr_SSS_d18Ow ar_SSS_d18Ow my_SSS_d18Ow \
0 2.730385 2.744889 2.747529 2.741694 2.738172
1 2.795991 2.802639 2.805744 2.804372 2.808415
2 2.837809 2.840615 2.840784 2.840007 2.851089
3 2.777538 2.785695 2.791531 2.788105 2.786381
4 2.809492 2.814421 2.818105 2.819479 2.818072
jn_SSS_d18Ow jl_SSS_d18Ow ag_SSS_d18Ow sp_SSS_d18Ow ot_SSS_d18Ow \
0 2.750210 2.759200 2.772942 2.769145 2.745299
1 2.828405 2.840431 2.852451 2.850035 2.827458
2 2.875549 2.889367 2.895949 2.892115 2.864288
3 2.799461 2.820661 2.842595 2.836395 2.806944
4 2.827237 2.844929 2.866786 2.863590 2.838464
nv_SSS_d18Ow dc_SSS_d18Ow
0 2.729710 2.726179
1 2.811291 2.800433
2 2.849760 2.841525
3 2.785955 2.777641
4 2.820463 2.812720
Calculate carbonate oxygen isotope value from SST and seawater oxygen isotope data using Grossman and Ku (1986) with the VPDB-VSMOW scale correction by Gonfiantini et al. (1995) and Dettman et al. (1999)¶
In [35]:
# Start with calculating d18Oc values for CESM model with 4x pre-industrial CO2
# Iterate over each model and calculate d18Oc values
for index, row in Lutetian_CESM_4PIC_model.iterrows():
# Iterate over each month
for month in months:
SST = row[f"{month}_SST"]
d18Ow = row[f"{month}_SSS_d18Ow"]
if not pd.isna(SST) and not pd.isna(d18Ow):
d18Oc = (20.6 - SST) / 4.34 + (d18Ow - 0.27)
else:
d18Oc = np.nan
# Add the calculated d18Oc value to the DataFrame
Lutetian_CESM_4PIC_model.loc[index, f"{month}_d18Oc"] = d18Oc
# Display the updated DataFrame
print(Lutetian_CESM_4PIC_model.head())
# Now calculating d18Oc values for CESM model with 2x pre-industrial CO2
# Iterate over each model and calculate d18Oc values
for index, row in Lutetian_CESM_2PIC_model.iterrows():
# Iterate over each month
for month in months:
SST = row[f"{month}_SST"]
d18Ow = row[f"{month}_SSS_d18Ow"]
if not pd.isna(SST) and not pd.isna(d18Ow):
d18Oc = (20.6 - SST) / 4.34 + (d18Ow - 0.27)
else:
d18Oc = np.nan
# Add the calculated d18Oc value to the DataFrame
Lutetian_CESM_2PIC_model.loc[index, f"{month}_d18Oc"] = d18Oc
# Display the updated DataFrame
print(Lutetian_CESM_2PIC_model.head())
# Now calculating d18Oc values for new HadCM model with 1x pre-industrial CO2
# Iterate over each model and calculate d18Oc values
for index, row in Lutetian_HadCM_new_1PIC_model.iterrows():
# Iterate over each month
for month in months:
SST = row[f"{month}_SST"]
d18Ow = row[f"{month}_SSS_d18Ow"]
if not pd.isna(SST) and not pd.isna(d18Ow):
d18Oc = (20.6 - SST) / 4.34 + (d18Ow - 0.27)
else:
d18Oc = np.nan
# Add the calculated d18Oc value to the DataFrame
Lutetian_HadCM_new_1PIC_model.loc[index, f"{month}_d18Oc"] = d18Oc
# Display the updated DataFrame
print(Lutetian_HadCM_new_1PIC_model.head())
# Now calculating d18Oc values for new HadCM model with 2x pre-industrial CO2
# Iterate over each model and calculate d18Oc values
for index, row in Lutetian_HadCM_new_2PIC_model.iterrows():
# Iterate over each month
for month in months:
SST = row[f"{month}_SST"]
d18Ow = row[f"{month}_SSS_d18Ow"]
if not pd.isna(SST) and not pd.isna(d18Ow):
d18Oc = (20.6 - SST) / 4.34 + (d18Ow - 0.27)
else:
d18Oc = np.nan
# Add the calculated d18Oc value to the DataFrame
Lutetian_HadCM_new_2PIC_model.loc[index, f"{month}_d18Oc"] = d18Oc
# Display the updated DataFrame
print(Lutetian_HadCM_new_2PIC_model.head())
# Now calculating d18Oc values for new HadCM model with 1056 ppm CO2
# Iterate over each model and calculate d18Oc values
for index, row in Lutetian_HadCM_new_1056ppm_model.iterrows():
# Iterate over each month
for month in months:
SST = row[f"{month}_SST"]
d18Ow = row[f"{month}_SSS_d18Ow"]
if not pd.isna(SST) and not pd.isna(d18Ow):
d18Oc = (20.6 - SST) / 4.34 + (d18Ow - 0.27)
else:
d18Oc = np.nan
# Add the calculated d18Oc value to the DataFrame
Lutetian_HadCM_new_1056ppm_model.loc[index, f"{month}_d18Oc"] = d18Oc
# Display the updated DataFrame
print(Lutetian_HadCM_new_1056ppm_model.head())
# Now calculating d18Oc values for old HadCM model with 2x pre-industrial CO2
# Iterate over each model and calculate d18Oc values
for index, row in Lutetian_HadCM_old_2PIC_model.iterrows():
# Iterate over each month
for month in months:
SST = row[f"{month}_SST"]
d18Ow = row[f"{month}_SSS_d18Ow"]
if not pd.isna(SST) and not pd.isna(d18Ow):
d18Oc = (20.6 - SST) / 4.34 + (d18Ow - 0.27)
else:
d18Oc = np.nan
# Add the calculated d18Oc value to the DataFrame
Lutetian_HadCM_old_2PIC_model.loc[index, f"{month}_d18Oc"] = d18Oc
# Display the updated DataFrame
print(Lutetian_HadCM_old_2PIC_model.head())
# Now calculating d18Oc values for old HadCM model with 4x pre-industrial CO2
# Iterate over each model and calculate d18Oc values
for index, row in Lutetian_HadCM_old_4PIC_model.iterrows():
# Iterate over each month
for month in months:
SST = row[f"{month}_SST"]
d18Ow = row[f"{month}_SSS_d18Ow"]
if not pd.isna(SST) and not pd.isna(d18Ow):
d18Oc = (20.6 - SST) / 4.34 + (d18Ow - 0.27)
else:
d18Oc = np.nan
# Add the calculated d18Oc value to the DataFrame
Lutetian_HadCM_old_4PIC_model.loc[index, f"{month}_d18Oc"] = d18Oc
# Display the updated DataFrame
print(Lutetian_HadCM_old_4PIC_model.head())
Cell ja_SAT fb_SAT mr_SAT ar_SAT my_SAT jn_SAT \
0 1 11.282648 12.089380 13.829187 16.709039 22.411493 27.940820
1 2 21.823206 22.185327 23.480707 25.735864 30.242242 35.107660
2 3 21.909296 22.198022 23.222040 25.234583 29.434015 34.056543
3 4 22.503198 22.530481 23.346246 25.152704 28.970605 33.480951
4 5 21.393762 21.576868 22.996118 25.669275 30.826440 36.038263
jl_SAT ag_SAT sp_SAT ... mr_d18Oc ar_d18Oc my_d18Oc \
0 30.968195 31.072290 26.694391 ... -0.873077 -1.040673 -1.619817
1 38.680688 39.036523 35.629755 ... -0.799470 -0.929937 -1.466061
2 38.089227 38.691492 35.554956 ... -0.754007 -0.877557 -1.403951
3 37.780298 38.492792 35.470605 ... -1.136514 -1.384207 -2.130491
4 40.872888 40.882013 36.701257 ... -1.122320 -1.360099 -2.106644
jn_d18Oc jl_d18Oc ag_d18Oc sp_d18Oc ot_d18Oc nv_d18Oc dc_d18Oc
0 -2.513306 -3.213928 -3.583698 -3.367792 -2.744058 -2.032903 -1.408096
1 -2.347593 -3.014437 -3.384486 -3.208780 -2.633968 -1.938649 -1.313754
2 -2.289134 -2.948919 -3.317429 -3.148663 -2.580306 -1.883936 -1.240408
3 -3.116770 -3.959694 -4.334650 -4.195826 -3.656621 -2.769984 -1.943248
4 -3.107112 -3.975039 -4.357027 -4.219610 -3.656945 -2.755215 -1.950705
[5 rows x 121 columns]
Cell ja_SAT fb_SAT mr_SAT ar_SAT my_SAT jn_SAT \
0 1 8.079706 8.682245 10.292291 13.623804 18.543329 22.827844
1 2 18.723108 19.036798 20.318903 22.775720 26.905450 31.019128
2 3 18.902612 19.163934 20.205408 22.355096 26.210016 30.252496
3 4 19.552850 19.557764 20.425623 22.352350 25.905756 29.882379
4 5 18.329370 18.452631 19.794916 22.507562 27.185938 31.563654
jl_SAT ag_SAT sp_SAT ... mr_d18Oc ar_d18Oc my_d18Oc \
0 25.661005 25.911890 22.544611 ... -0.251207 -0.457940 -1.035783
1 34.275934 34.816797 31.946375 ... -0.186319 -0.348003 -0.886515
2 34.047083 34.686151 32.002588 ... -0.141044 -0.294629 -0.829306
3 33.956262 34.617273 31.891870 ... -0.279467 -0.573045 -1.337027
4 36.184412 36.466760 32.711786 ... -0.264183 -0.545776 -1.311192
jn_d18Oc jl_d18Oc ag_d18Oc sp_d18Oc ot_d18Oc nv_d18Oc dc_d18Oc
0 -1.881269 -2.576888 -2.909747 -2.685377 -2.032326 -1.304283 -0.662541
1 -1.713226 -2.383224 -2.730425 -2.549758 -1.941088 -1.222027 -0.576549
2 -1.654628 -2.321103 -2.669299 -2.494446 -1.898522 -1.172672 -0.504181
3 -2.293682 -3.076797 -3.480791 -3.346192 -2.751792 -1.868905 -1.014725
4 -2.280590 -3.088334 -3.501189 -3.361654 -2.745354 -1.846001 -1.017308
[5 rows x 121 columns]
Cell ja_SAT fb_SAT mr_SAT ar_SAT my_SAT jn_SAT \
0 1 8.052789 7.992517 8.733209 10.359064 13.972986 19.524438
1 2 5.543665 5.446466 6.303369 8.327386 12.788965 18.906274
2 3 5.441797 5.020135 5.603723 7.323083 11.379724 17.331293
3 4 11.657343 11.682520 12.354303 13.548639 16.459161 21.680658
4 5 3.336206 5.344659 8.210504 11.033441 15.833429 20.868097
jl_SAT ag_SAT sp_SAT ... mr_d18Oc ar_d18Oc my_d18Oc \
0 24.154474 25.112024 22.214838 ... 1.371498 1.247086 0.758522
1 23.355554 24.378473 21.271326 ... 1.335512 1.239549 0.778126
2 22.398523 23.914362 21.047418 ... 1.927412 1.703638 1.036772
3 25.439905 26.119257 24.086908 ... 1.362663 1.313629 0.937249
4 23.159937 23.440515 20.537500 ... 1.588500 1.521920 1.041418
jn_d18Oc jl_d18Oc ag_d18Oc sp_d18Oc ot_d18Oc nv_d18Oc dc_d18Oc
0 -0.204534 -0.812510 -0.975899 -0.837487 -0.201872 0.513953 0.996075
1 -0.170957 -0.769120 -0.937684 -0.817608 -0.226889 0.443263 0.944667
2 -0.037282 -0.707649 -0.900912 -0.713900 -0.038772 0.678716 1.281174
3 -0.104788 -0.920888 -1.116881 -0.834474 -0.204629 0.436719 0.866669
4 -0.078969 -0.849627 -1.022401 -0.739666 -0.096670 0.608511 1.076184
[5 rows x 121 columns]
Cell ja_SAT fb_SAT mr_SAT ar_SAT my_SAT jn_SAT \
0 1 12.032495 11.765405 12.540948 14.017786 17.638818 22.951166
1 2 10.032343 9.614069 10.567499 12.368372 16.857782 23.125818
2 3 10.042474 9.279749 9.883508 11.388208 15.628229 21.994348
3 4 15.231805 14.956903 15.680139 16.795190 19.790338 24.812463
4 5 7.854364 8.944025 11.926355 14.481989 19.159235 24.058344
jl_SAT ag_SAT sp_SAT ... mr_d18Oc ar_d18Oc my_d18Oc \
0 27.410181 28.291254 25.576105 ... 0.868118 0.733481 0.253210
1 27.034113 27.580316 24.560754 ... 0.821608 0.719385 0.261080
2 26.338739 27.108881 24.157251 ... 1.337524 1.117325 0.431039
3 28.288263 28.865594 26.970605 ... 0.858103 0.800370 0.399973
4 26.157434 26.275842 23.426965 ... 1.056110 0.963794 0.449333
jn_d18Oc jl_d18Oc ag_d18Oc sp_d18Oc ot_d18Oc nv_d18Oc dc_d18Oc
0 -0.624277 -1.172320 -1.371561 -1.284367 -0.671433 0.044402 0.524114
1 -0.632101 -1.163279 -1.343080 -1.269951 -0.683597 -0.018013 0.460165
2 -0.589934 -1.150781 -1.326708 -1.184240 -0.524181 0.173744 0.744560
3 -0.562882 -1.351832 -1.570835 -1.337008 -0.711914 -0.066910 0.371023
4 -0.620587 -1.316765 -1.477848 -1.240102 -0.594261 0.094205 0.551104
[5 rows x 121 columns]
Cell ja_SAT fb_SAT mr_SAT ar_SAT my_SAT jn_SAT \
0 1 14.752985 14.494897 14.980402 16.575220 20.000818 25.204980
1 2 12.996912 12.753046 13.208704 15.260828 19.392999 25.608850
2 3 13.127679 12.599512 12.679742 14.343317 18.218500 24.699243
3 4 17.809625 17.621484 17.975031 19.288171 22.094263 26.878717
4 5 11.005304 12.533258 14.417230 17.510217 21.609277 26.559656
jl_SAT ag_SAT sp_SAT ... mr_d18Oc ar_d18Oc my_d18Oc \
0 29.662347 30.615137 28.027460 ... 0.462286 0.319492 -0.117976
1 29.630823 30.056573 27.234857 ... 0.420872 0.318065 -0.094086
2 28.905939 29.489587 26.775018 ... 0.896351 0.671169 0.053261
3 30.409326 31.094934 29.279382 ... 0.450243 0.387609 -0.001984
4 29.221490 29.027551 26.355951 ... 0.630011 0.541336 0.059345
jn_d18Oc jl_d18Oc ag_d18Oc sp_d18Oc ot_d18Oc nv_d18Oc dc_d18Oc
0 -0.893339 -1.401199 -1.663044 -1.615631 -1.046066 -0.307489 0.145241
1 -0.916587 -1.447047 -1.683003 -1.627250 -1.087843 -0.367076 0.087612
2 -0.909284 -1.470256 -1.696925 -1.566963 -0.965545 -0.187116 0.359146
3 -0.865929 -1.592123 -1.891272 -1.687934 -1.105678 -0.449740 -0.027298
4 -0.917299 -1.601847 -1.839061 -1.629993 -1.019839 -0.290049 0.147674
[5 rows x 121 columns]
Cell ja_SAT fb_SAT mr_SAT ar_SAT my_SAT jn_SAT \
0 1 16.109460 16.027917 16.557794 17.969568 20.876367 24.644067
1 2 14.491327 14.465814 15.096796 16.632349 20.268671 25.111902
2 3 14.220056 13.856958 14.220026 15.771631 19.406030 24.685876
3 4 18.878229 18.639429 18.971124 20.211633 22.895258 26.576044
4 5 10.043237 12.065576 15.218744 18.920587 23.262933 28.577478
jl_SAT ag_SAT sp_SAT ... mr_d18Oc ar_d18Oc my_d18Oc \
0 28.467523 30.818384 29.538446 ... 2.291533 2.078768 1.546487
1 29.014185 31.189355 29.456750 ... 2.390405 2.190546 1.623027
2 28.935297 30.628656 28.646417 ... 2.603273 2.345437 1.680343
3 29.851801 31.372522 30.517450 ... 2.481481 2.289573 1.718124
4 31.001825 31.300806 27.688562 ... 2.655554 2.478183 1.930503
jn_d18Oc jl_d18Oc ag_d18Oc sp_d18Oc ot_d18Oc nv_d18Oc dc_d18Oc
0 0.806258 0.375497 0.130180 0.084777 0.546801 1.247116 1.817300
1 0.810241 0.360604 0.118713 0.102642 0.590819 1.283430 1.878680
2 0.817935 0.410225 0.190672 0.165803 0.717999 1.441631 2.071117
3 0.868131 0.315540 0.057481 0.142721 0.749011 1.494767 2.041653
4 1.077646 0.468864 0.198060 0.267340 0.940486 1.678493 2.245521
[5 rows x 121 columns]
Cell ja_SAT fb_SAT mr_SAT ar_SAT my_SAT jn_SAT \
0 1 16.109460 16.027917 16.557794 17.969568 20.876367 24.644067
1 2 14.491327 14.465814 15.096796 16.632349 20.268671 25.111902
2 3 14.220056 13.856958 14.220026 15.771631 19.406030 24.685876
3 4 18.878229 18.639429 18.971124 20.211633 22.895258 26.576044
4 5 10.043237 12.065576 15.218744 18.920587 23.262933 28.577478
jl_SAT ag_SAT sp_SAT ... mr_d18Oc ar_d18Oc my_d18Oc \
0 28.467523 30.818384 29.538446 ... 2.291533 2.078768 1.546487
1 29.014185 31.189355 29.456750 ... 2.390405 2.190546 1.623027
2 28.935297 30.628656 28.646417 ... 2.603273 2.345437 1.680343
3 29.851801 31.372522 30.517450 ... 2.481481 2.289573 1.718124
4 31.001825 31.300806 27.688562 ... 2.655554 2.478183 1.930503
jn_d18Oc jl_d18Oc ag_d18Oc sp_d18Oc ot_d18Oc nv_d18Oc dc_d18Oc
0 0.806258 0.375497 0.130180 0.084777 0.546801 1.247116 1.817300
1 0.810241 0.360604 0.118713 0.102642 0.590819 1.283430 1.878680
2 0.817935 0.410225 0.190672 0.165803 0.717999 1.441631 2.071117
3 0.868131 0.315540 0.057481 0.142721 0.749011 1.494767 2.041653
4 1.077646 0.468864 0.198060 0.267340 0.940486 1.678493 2.245521
[5 rows x 121 columns]
Calculate the monthly prior for model SST- and SAT-derived D47 values and SSS-derived seawater oxygen isotope values with propagated uncertainty¶
In [36]:
HadCM_old_4PIC_model_variances_SST = Lutetian_HadCM_old_4PIC_model[[f"{month}_SST_D47" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_old_4PIC_model_variances_SAT = Lutetian_HadCM_old_4PIC_model[[f"{month}_SAT_D47" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_old_4PIC_model_variances_d18Ow = Lutetian_HadCM_old_4PIC_model[[f"{month}_SSS_d18Ow" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_old_4PIC_model_variances_d18Oc = Lutetian_HadCM_old_4PIC_model[[f"{month}_d18Oc" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_old_4PIC_calibration_variances_SST = (Lutetian_HadCM_old_4PIC_model[[f"{month}_SST_D47_SE" for month in months]] ** 2).mean(axis = 0, skipna = True) # Compute variance on measurements
HadCM_old_4PIC_calibration_variances_SAT = (Lutetian_HadCM_old_4PIC_model[[f"{month}_SAT_D47_SE" for month in months]] ** 2).mean(axis = 0, skipna = True) # Compute variance on measurements
In [37]:
# Set the weights of the data based on the standard errors
weights_monthly_CESM_4PIC_SST_D47 = 1 / Lutetian_CESM_4PIC_model[[f"{month}_SST_D47_SE" for month in months]] ** 2
weights_monthly_CESM_4PIC_SAT_D47 = 1 / Lutetian_CESM_4PIC_model[[f"{month}_SAT_D47_SE" for month in months]] ** 2
weights_monthly_CESM_2PIC_SST_D47 = 1 / Lutetian_CESM_2PIC_model[[f"{month}_SST_D47_SE" for month in months]] ** 2
weights_monthly_CESM_2PIC_SAT_D47 = 1 / Lutetian_CESM_2PIC_model[[f"{month}_SAT_D47_SE" for month in months]] ** 2
weights_monthly_HadCM_new_1PIC_SST_D47 = 1 / Lutetian_HadCM_new_1PIC_model[[f"{month}_SST_D47_SE" for month in months]] ** 2
weights_monthly_HadCM_new_1PIC_SAT_D47 = 1 / Lutetian_HadCM_new_1PIC_model[[f"{month}_SAT_D47_SE" for month in months]] ** 2
weights_monthly_HadCM_new_2PIC_SST_D47 = 1 / Lutetian_HadCM_new_2PIC_model[[f"{month}_SST_D47_SE" for month in months]] ** 2
weights_monthly_HadCM_new_2PIC_SAT_D47 = 1 / Lutetian_HadCM_new_2PIC_model[[f"{month}_SAT_D47_SE" for month in months]] ** 2
weights_monthly_HadCM_new_1056ppm_SST_D47 = 1 / Lutetian_HadCM_new_1056ppm_model[[f"{month}_SST_D47_SE" for month in months]] ** 2
weights_monthly_HadCM_new_1056ppm_SAT_D47 = 1 / Lutetian_HadCM_new_1056ppm_model[[f"{month}_SAT_D47_SE" for month in months]] ** 2
weights_monthly_HadCM_old_2PIC_SST_D47 = 1 / Lutetian_HadCM_old_2PIC_model[[f"{month}_SST_D47_SE" for month in months]] ** 2
weights_monthly_HadCM_old_2PIC_SAT_D47 = 1 / Lutetian_HadCM_old_2PIC_model[[f"{month}_SAT_D47_SE" for month in months]] ** 2
weights_monthly_HadCM_old_4PIC_SST_D47 = 1 / Lutetian_HadCM_old_4PIC_model[[f"{month}_SST_D47_SE" for month in months]] ** 2
weights_monthly_HadCM_old_4PIC_SAT_D47 = 1 / Lutetian_HadCM_old_4PIC_model[[f"{month}_SAT_D47_SE" for month in months]] ** 2
# Change the column suffixes from "_D47_SE" to "_D47" in weights_monthly_CESM_4PIC_SST_D47 to match the headers of the D47 matrix later for multiplication
weights_monthly_CESM_4PIC_SST_D47.columns = [col.replace('_SST_D47_SE', '_SST_D47') for col in weights_monthly_CESM_4PIC_SST_D47.columns]
weights_monthly_CESM_4PIC_SAT_D47.columns = [col.replace('_SAT_D47_SE', '_SAT_D47') for col in weights_monthly_CESM_4PIC_SAT_D47.columns]
weights_monthly_CESM_2PIC_SST_D47.columns = [col.replace('_SST_D47_SE', '_SST_D47') for col in weights_monthly_CESM_2PIC_SST_D47.columns]
weights_monthly_CESM_2PIC_SAT_D47.columns = [col.replace('_SAT_D47_SE', '_SAT_D47') for col in weights_monthly_CESM_2PIC_SAT_D47.columns]
weights_monthly_HadCM_new_1PIC_SST_D47.columns = [col.replace('_SST_D47_SE', '_SST_D47') for col in weights_monthly_HadCM_new_1PIC_SST_D47.columns]
weights_monthly_HadCM_new_1PIC_SAT_D47.columns = [col.replace('_SAT_D47_SE', '_SAT_D47') for col in weights_monthly_HadCM_new_1PIC_SAT_D47.columns]
weights_monthly_HadCM_new_2PIC_SST_D47.columns = [col.replace('_SST_D47_SE', '_SST_D47') for col in weights_monthly_HadCM_new_2PIC_SST_D47.columns]
weights_monthly_HadCM_new_2PIC_SAT_D47.columns = [col.replace('_SAT_D47_SE', '_SAT_D47') for col in weights_monthly_HadCM_new_2PIC_SAT_D47.columns]
weights_monthly_HadCM_new_1056ppm_SST_D47.columns = [col.replace('_SST_D47_SE', '_SST_D47') for col in weights_monthly_HadCM_new_1056ppm_SST_D47.columns]
weights_monthly_HadCM_new_1056ppm_SAT_D47.columns = [col.replace('_SAT_D47_SE', '_SAT_D47') for col in weights_monthly_HadCM_new_1056ppm_SAT_D47.columns]
weights_monthly_HadCM_old_2PIC_SST_D47.columns = [col.replace('_SST_D47_SE', '_SST_D47') for col in weights_monthly_HadCM_old_2PIC_SST_D47.columns]
weights_monthly_HadCM_old_2PIC_SAT_D47.columns = [col.replace('_SAT_D47_SE', '_SAT_D47') for col in weights_monthly_HadCM_old_2PIC_SAT_D47.columns]
weights_monthly_HadCM_old_4PIC_SST_D47.columns = [col.replace('_SST_D47_SE', '_SST_D47') for col in weights_monthly_HadCM_old_4PIC_SST_D47.columns]
weights_monthly_HadCM_old_4PIC_SAT_D47.columns = [col.replace('_SAT_D47_SE', '_SAT_D47') for col in weights_monthly_HadCM_old_4PIC_SAT_D47.columns]
# Prior D47 estimates from CESM model with 4x preindustrial pCO2 (weighted mean)
mu_prior_CESM_4PIC_SST_D47_monthly = np.array((Lutetian_CESM_4PIC_model[[f"{month}_SST_D47" for month in months]] * weights_monthly_CESM_4PIC_SST_D47).sum(axis = 0, skipna = True) / weights_monthly_CESM_4PIC_SST_D47.sum(axis = 0, skipna = True)) # Calculate weighted monthly mean D47 values and convert to numpy array
mu_prior_CESM_4PIC_SAT_D47_monthly = np.array((Lutetian_CESM_4PIC_model[[f"{month}_SAT_D47" for month in months]] * weights_monthly_CESM_4PIC_SAT_D47).sum(axis = 0, skipna = True) / weights_monthly_CESM_4PIC_SAT_D47.sum(axis = 0, skipna = True)) # Calculate weighted monthly mean D47 values and convert to numpy array
mu_prior_CESM_2PIC_SST_D47_monthly = np.array((Lutetian_CESM_2PIC_model[[f"{month}_SST_D47" for month in months]] * weights_monthly_CESM_2PIC_SST_D47).sum(axis = 0, skipna = True) / weights_monthly_CESM_2PIC_SST_D47.sum(axis = 0, skipna = True)) # Calculate weighted monthly mean D47 values and convert to numpy array
mu_prior_CESM_2PIC_SAT_D47_monthly = np.array((Lutetian_CESM_2PIC_model[[f"{month}_SAT_D47" for month in months]] * weights_monthly_CESM_2PIC_SAT_D47).sum(axis = 0, skipna = True) / weights_monthly_CESM_2PIC_SAT_D47.sum(axis = 0, skipna = True)) # Calculate weighted monthly mean D47 values and convert to numpy array
mu_prior_HadCM_new_1PIC_SST_D47_monthly = np.array((Lutetian_HadCM_new_1PIC_model[[f"{month}_SST_D47" for month in months]] * weights_monthly_HadCM_new_1PIC_SST_D47).sum(axis = 0, skipna = True) / weights_monthly_HadCM_new_1PIC_SST_D47.sum(axis = 0, skipna = True)) # Calculate weighted monthly mean D47 values and convert to numpy array
mu_prior_HadCM_new_1PIC_SAT_D47_monthly = np.array((Lutetian_HadCM_new_1PIC_model[[f"{month}_SAT_D47" for month in months]] * weights_monthly_HadCM_new_1PIC_SAT_D47).sum(axis = 0, skipna = True) / weights_monthly_HadCM_new_1PIC_SAT_D47.sum(axis = 0, skipna = True)) # Calculate weighted monthly mean D47 values and convert to numpy array
mu_prior_HadCM_new_2PIC_SST_D47_monthly = np.array((Lutetian_HadCM_new_2PIC_model[[f"{month}_SST_D47" for month in months]] * weights_monthly_HadCM_new_2PIC_SST_D47).sum(axis = 0, skipna = True) / weights_monthly_HadCM_new_2PIC_SST_D47.sum(axis = 0, skipna = True)) # Calculate weighted monthly mean D47 values and convert to numpy array
mu_prior_HadCM_new_2PIC_SAT_D47_monthly = np.array((Lutetian_HadCM_new_2PIC_model[[f"{month}_SAT_D47" for month in months]] * weights_monthly_HadCM_new_2PIC_SAT_D47).sum(axis = 0, skipna = True) / weights_monthly_HadCM_new_2PIC_SAT_D47.sum(axis = 0, skipna = True)) # Calculate weighted monthly mean D47 values and convert to numpy array
mu_prior_HadCM_new_1056ppm_SST_D47_monthly = np.array((Lutetian_HadCM_new_1056ppm_model[[f"{month}_SST_D47" for month in months]] * weights_monthly_HadCM_new_1056ppm_SST_D47).sum(axis = 0, skipna = True) / weights_monthly_HadCM_new_1056ppm_SST_D47.sum(axis = 0, skipna = True)) # Calculate weighted monthly mean D47 values and convert to numpy array
mu_prior_HadCM_new_1056ppm_SAT_D47_monthly = np.array((Lutetian_HadCM_new_1056ppm_model[[f"{month}_SAT_D47" for month in months]] * weights_monthly_HadCM_new_1056ppm_SAT_D47).sum(axis = 0, skipna = True) / weights_monthly_HadCM_new_1056ppm_SAT_D47.sum(axis = 0, skipna = True)) # Calculate weighted monthly mean D47 values and convert to numpy array
mu_prior_HadCM_old_2PIC_SST_D47_monthly = np.array((Lutetian_HadCM_old_2PIC_model[[f"{month}_SST_D47" for month in months]] * weights_monthly_HadCM_old_2PIC_SST_D47).sum(axis = 0, skipna = True) / weights_monthly_HadCM_old_2PIC_SST_D47.sum(axis = 0, skipna = True)) # Calculate weighted monthly mean D47 values and convert to numpy array
mu_prior_HadCM_old_2PIC_SAT_D47_monthly = np.array((Lutetian_HadCM_old_2PIC_model[[f"{month}_SAT_D47" for month in months]] * weights_monthly_HadCM_old_2PIC_SAT_D47).sum(axis = 0, skipna = True) / weights_monthly_HadCM_old_2PIC_SAT_D47.sum(axis = 0, skipna = True)) # Calculate weighted monthly mean D47 values and convert to numpy array
mu_prior_HadCM_old_4PIC_SST_D47_monthly = np.array((Lutetian_HadCM_old_4PIC_model[[f"{month}_SST_D47" for month in months]] * weights_monthly_HadCM_old_4PIC_SST_D47).sum(axis = 0, skipna = True) / weights_monthly_HadCM_old_4PIC_SST_D47.sum(axis = 0, skipna = True)) # Calculate weighted monthly mean D47 values and convert to numpy array
mu_prior_HadCM_old_4PIC_SAT_D47_monthly = np.array((Lutetian_HadCM_old_4PIC_model[[f"{month}_SAT_D47" for month in months]] * weights_monthly_HadCM_old_4PIC_SAT_D47).sum(axis = 0, skipna = True) / weights_monthly_HadCM_old_4PIC_SAT_D47.sum(axis = 0, skipna = True)) # Calculate weighted monthly mean D47 values and convert to numpy array
# Calculate simple (unweighted) mean for monthly d18Ow values
mu_prior_CESM_4PIC_SSS_d18Ow_monthly = np.array(Lutetian_CESM_4PIC_model[[f"{month}_SSS_d18Ow" for month in months]].mean(axis=0, skipna=True))
mu_prior_CESM_2PIC_SSS_d18Ow_monthly = np.array(Lutetian_CESM_2PIC_model[[f"{month}_SSS_d18Ow" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_new_1PIC_SSS_d18Ow_monthly = np.array(Lutetian_HadCM_new_1PIC_model[[f"{month}_SSS_d18Ow" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_new_2PIC_SSS_d18Ow_monthly = np.array(Lutetian_HadCM_new_2PIC_model[[f"{month}_SSS_d18Ow" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_new_1056ppm_SSS_d18Ow_monthly = np.array(Lutetian_HadCM_new_1056ppm_model[[f"{month}_SSS_d18Ow" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_old_2PIC_SSS_d18Ow_monthly = np.array(Lutetian_HadCM_old_2PIC_model[[f"{month}_SSS_d18Ow" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_old_4PIC_SSS_d18Ow_monthly = np.array(Lutetian_HadCM_old_4PIC_model[[f"{month}_SSS_d18Ow" for month in months]].mean(axis=0, skipna=True))
mu_prior_CESM_4PIC_d18Oc_monthly = np.array(Lutetian_CESM_4PIC_model[[f"{month}_d18Oc" for month in months]].mean(axis=0, skipna=True))
mu_prior_CESM_2PIC_d18Oc_monthly = np.array(Lutetian_CESM_2PIC_model[[f"{month}_d18Oc" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_new_1PIC_d18Oc_monthly = np.array(Lutetian_HadCM_new_1PIC_model[[f"{month}_d18Oc" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_new_2PIC_d18Oc_monthly = np.array(Lutetian_HadCM_new_2PIC_model[[f"{month}_d18Oc" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_new_1056ppm_d18Oc_monthly = np.array(Lutetian_HadCM_new_1056ppm_model[[f"{month}_d18Oc" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_old_2PIC_d18Oc_monthly = np.array(Lutetian_HadCM_old_2PIC_model[[f"{month}_d18Oc" for month in months]].mean(axis=0, skipna=True))
mu_prior_HadCM_old_4PIC_d18Oc_monthly = np.array(Lutetian_HadCM_old_4PIC_model[[f"{month}_d18Oc" for month in months]].mean(axis=0, skipna=True))
# Decompose variance within and between model outcomes
CESM_4PIC_model_variances_SST = Lutetian_CESM_4PIC_model[[f"{month}_SST_D47" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
CESM_4PIC_model_variances_SAT = Lutetian_CESM_4PIC_model[[f"{month}_SAT_D47" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
CESM_4PIC_model_variances_d18Ow = Lutetian_CESM_4PIC_model[[f"{month}_SSS_d18Ow" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
CESM_4PIC_model_variances_d18Oc = Lutetian_CESM_4PIC_model[[f"{month}_d18Oc" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
CESM_4PIC_calibration_variances_SST = (Lutetian_CESM_4PIC_model[[f"{month}_SST_D47_SE" for month in months]] ** 2).mean(axis = 0, skipna = True) # Compute variance on measurements
CESM_4PIC_calibration_variances_SAT = (Lutetian_CESM_4PIC_model[[f"{month}_SAT_D47_SE" for month in months]] ** 2).mean(axis = 0, skipna = True) # Compute variance on measurements
CESM_2PIC_model_variances_SST = Lutetian_CESM_2PIC_model[[f"{month}_SST_D47" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
CESM_2PIC_model_variances_SAT = Lutetian_CESM_2PIC_model[[f"{month}_SAT_D47" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
CESM_2PIC_model_variances_d18Ow = Lutetian_CESM_2PIC_model[[f"{month}_SSS_d18Ow" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
CESM_2PIC_model_variances_d18Oc = Lutetian_CESM_2PIC_model[[f"{month}_d18Oc" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
CESM_2PIC_calibration_variances_SST = (Lutetian_CESM_2PIC_model[[f"{month}_SST_D47_SE" for month in months]] ** 2).mean(axis = 0, skipna = True) # Compute variance on measurements
CESM_2PIC_calibration_variances_SAT = (Lutetian_CESM_2PIC_model[[f"{month}_SAT_D47_SE" for month in months]] ** 2).mean(axis = 0, skipna = True) # Compute variance on measurements
HadCM_new_1PIC_model_variances_SST = Lutetian_HadCM_new_1PIC_model[[f"{month}_SST_D47" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_new_1PIC_model_variances_SAT = Lutetian_HadCM_new_1PIC_model[[f"{month}_SAT_D47" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_new_1PIC_model_variances_d18Ow = Lutetian_HadCM_new_1PIC_model[[f"{month}_SSS_d18Ow" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_new_1PIC_model_variances_d18Oc = Lutetian_HadCM_new_1PIC_model[[f"{month}_d18Oc" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_new_1PIC_calibration_variances_SST = (Lutetian_HadCM_new_1PIC_model[[f"{month}_SST_D47_SE" for month in months]] ** 2).mean(axis = 0, skipna = True) # Compute variance on measurements
HadCM_new_1PIC_calibration_variances_SAT = (Lutetian_HadCM_new_1PIC_model[[f"{month}_SAT_D47_SE" for month in months]] ** 2).mean(axis = 0, skipna = True) # Compute variance on measurements
HadCM_new_2PIC_model_variances_SST = Lutetian_HadCM_new_2PIC_model[[f"{month}_SST_D47" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_new_2PIC_model_variances_SAT = Lutetian_HadCM_new_2PIC_model[[f"{month}_SAT_D47" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_new_2PIC_model_variances_d18Ow = Lutetian_HadCM_new_2PIC_model[[f"{month}_SSS_d18Ow" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_new_2PIC_model_variances_d18Oc = Lutetian_HadCM_new_2PIC_model[[f"{month}_d18Oc" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_new_2PIC_calibration_variances_SST = (Lutetian_HadCM_new_2PIC_model[[f"{month}_SST_D47_SE" for month in months]] ** 2).mean(axis = 0, skipna = True) # Compute variance on measurements
HadCM_new_2PIC_calibration_variances_SAT = (Lutetian_HadCM_new_2PIC_model[[f"{month}_SAT_D47_SE" for month in months]] ** 2).mean(axis = 0, skipna = True) # Compute variance on measurements
HadCM_new_1056ppm_model_variances_SST = Lutetian_HadCM_new_1056ppm_model[[f"{month}_SST_D47" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_new_1056ppm_model_variances_SAT = Lutetian_HadCM_new_1056ppm_model[[f"{month}_SAT_D47" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_new_1056ppm_model_variances_d18Ow = Lutetian_HadCM_new_1056ppm_model[[f"{month}_SSS_d18Ow" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_new_1056ppm_model_variances_d18Oc = Lutetian_HadCM_new_1056ppm_model[[f"{month}_d18Oc" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_new_1056ppm_calibration_variances_SST = (Lutetian_HadCM_new_1056ppm_model[[f"{month}_SST_D47_SE" for month in months]] ** 2).mean(axis = 0, skipna = True) # Compute variance on measurements
HadCM_new_1056ppm_calibration_variances_SAT = (Lutetian_HadCM_new_1056ppm_model[[f"{month}_SAT_D47_SE" for month in months]] ** 2).mean(axis = 0, skipna = True) # Compute variance on measurements
HadCM_old_2PIC_model_variances_SST = Lutetian_HadCM_old_2PIC_model[[f"{month}_SST_D47" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_old_2PIC_model_variances_SAT = Lutetian_HadCM_old_2PIC_model[[f"{month}_SAT_D47" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_old_2PIC_model_variances_d18Ow = Lutetian_HadCM_old_2PIC_model[[f"{month}_SSS_d18Ow" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_old_2PIC_model_variances_d18Oc = Lutetian_HadCM_old_2PIC_model[[f"{month}_d18Oc" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_old_2PIC_calibration_variances_SST = (Lutetian_HadCM_old_2PIC_model[[f"{month}_SST_D47_SE" for month in months]] ** 2).mean(axis = 0, skipna = True) # Compute variance on measurements
HadCM_old_2PIC_calibration_variances_SAT = (Lutetian_HadCM_old_2PIC_model[[f"{month}_SAT_D47_SE" for month in months]] ** 2).mean(axis = 0, skipna = True) # Compute variance on measurements
HadCM_old_4PIC_model_variances_SST = Lutetian_HadCM_old_4PIC_model[[f"{month}_SST_D47" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_old_4PIC_model_variances_SAT = Lutetian_HadCM_old_4PIC_model[[f"{month}_SAT_D47" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_old_4PIC_model_variances_d18Ow = Lutetian_HadCM_old_4PIC_model[[f"{month}_SSS_d18Ow" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_old_4PIC_model_variances_d18Oc = Lutetian_HadCM_old_4PIC_model[[f"{month}_d18Oc" for month in months]].var(axis = 0, ddof = 1) # Compute variance across models
HadCM_old_4PIC_calibration_variances_SST = (Lutetian_HadCM_old_4PIC_model[[f"{month}_SST_D47_SE" for month in months]] ** 2).mean(axis = 0, skipna = True) # Compute variance on measurements
HadCM_old_4PIC_calibration_variances_SAT = (Lutetian_HadCM_old_4PIC_model[[f"{month}_SAT_D47_SE" for month in months]] ** 2).mean(axis = 0, skipna = True) # Compute variance on measurements
# Covariance between months in prior D47 estimates from CESM model with 4x preindustrial pCO2 (weighted covariance matrix)
cov_raw_CESM_4PIC_monthly_SST = np.cov(Lutetian_CESM_4PIC_model[[f"{month}_SST_D47" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_CESM_4PIC_monthly_SAT = np.cov(Lutetian_CESM_4PIC_model[[f"{month}_SAT_D47" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_CESM_4PIC_monthly_d18Ow = np.cov(Lutetian_CESM_4PIC_model[[f"{month}_SSS_d18Ow" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_CESM_4PIC_monthly_d18Oc = np.cov(Lutetian_CESM_4PIC_model[[f"{month}_d18Oc" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_prior_CESM_4PIC_SST_D47_monthly = cov_raw_CESM_4PIC_monthly_SST.copy() # Copy covariance matrix to add uncertainty coming from the measurements
cov_prior_CESM_4PIC_SAT_D47_monthly = cov_raw_CESM_4PIC_monthly_SAT.copy() # Copy covariance matrix to add uncertainty coming from the measurements
np.fill_diagonal(cov_prior_CESM_4PIC_SST_D47_monthly, np.diagonal(cov_raw_CESM_4PIC_monthly_SST) + CESM_4PIC_calibration_variances_SST) # Add diagonal terms for measurement uncertainties (which have no covariance between models)
np.fill_diagonal(cov_prior_CESM_4PIC_SAT_D47_monthly, np.diagonal(cov_raw_CESM_4PIC_monthly_SAT) + CESM_4PIC_calibration_variances_SAT) # Add diagonal terms for measurement uncertainties (which have no covariance between models)
cov_raw_CESM_2PIC_monthly_SST = np.cov(Lutetian_CESM_2PIC_model[[f"{month}_SST_D47" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_CESM_2PIC_monthly_SAT = np.cov(Lutetian_CESM_2PIC_model[[f"{month}_SAT_D47" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_CESM_2PIC_monthly_d18Ow = np.cov(Lutetian_CESM_2PIC_model[[f"{month}_SSS_d18Ow" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_CESM_2PIC_monthly_d18Oc = np.cov(Lutetian_CESM_2PIC_model[[f"{month}_d18Oc" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_prior_CESM_2PIC_SST_D47_monthly = cov_raw_CESM_2PIC_monthly_SST.copy() # Copy covariance matrix to add uncertainty coming from the measurements
cov_prior_CESM_2PIC_SAT_D47_monthly = cov_raw_CESM_2PIC_monthly_SAT.copy() # Copy covariance matrix to add uncertainty coming from the measurements
np.fill_diagonal(cov_prior_CESM_2PIC_SST_D47_monthly, np.diagonal(cov_raw_CESM_2PIC_monthly_SST) + CESM_2PIC_calibration_variances_SST) # Add diagonal terms for measurement uncertainties (which have no covariance between models)
np.fill_diagonal(cov_prior_CESM_2PIC_SAT_D47_monthly, np.diagonal(cov_raw_CESM_2PIC_monthly_SAT) + CESM_2PIC_calibration_variances_SAT) # Add diagonal terms for measurement
cov_raw_HadCM_new_1PIC_monthly_SST = np.cov(Lutetian_HadCM_new_1PIC_model[[f"{month}_SST_D47" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_HadCM_new_1PIC_monthly_SAT = np.cov(Lutetian_HadCM_new_1PIC_model[[f"{month}_SAT_D47" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_HadCM_new_1PIC_monthly_d18Ow = np.cov(Lutetian_HadCM_new_1PIC_model[[f"{month}_SSS_d18Ow" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_HadCM_new_1PIC_monthly_d18Oc = np.cov(Lutetian_HadCM_new_1PIC_model[[f"{month}_d18Oc" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_prior_HadCM_new_1PIC_SST_D47_monthly = cov_raw_HadCM_new_1PIC_monthly_SST.copy() # Copy covariance matrix to add uncertainty coming from the measurements
cov_prior_HadCM_new_1PIC_SAT_D47_monthly = cov_raw_HadCM_new_1PIC_monthly_SAT.copy() # Copy covariance matrix to add uncertainty coming from the measurements
np.fill_diagonal(cov_prior_HadCM_new_1PIC_SST_D47_monthly, np.diagonal(cov_raw_HadCM_new_1PIC_monthly_SST) + HadCM_new_1PIC_calibration_variances_SST) # Add diagonal terms for measurement uncertainties (which have no covariance between models)
np.fill_diagonal(cov_prior_HadCM_new_1PIC_SAT_D47_monthly, np.diagonal(cov_raw_HadCM_new_1PIC_monthly_SAT) + HadCM_new_1PIC_calibration_variances_SAT) # Add diagonal terms for measurement uncertainties (which have no covariance between models)
cov_raw_HadCM_new_2PIC_monthly_SST = np.cov(Lutetian_HadCM_new_2PIC_model[[f"{month}_SST_D47" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_HadCM_new_2PIC_monthly_SAT = np.cov(Lutetian_HadCM_new_2PIC_model[[f"{month}_SAT_D47" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_HadCM_new_2PIC_monthly_d18Ow = np.cov(Lutetian_HadCM_new_2PIC_model[[f"{month}_SSS_d18Ow" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_HadCM_new_2PIC_monthly_d18Oc = np.cov(Lutetian_HadCM_new_2PIC_model[[f"{month}_d18Oc" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_prior_HadCM_new_2PIC_SST_D47_monthly = cov_raw_HadCM_new_2PIC_monthly_SST.copy() # Copy covariance matrix to add uncertainty coming from the measurements
cov_prior_HadCM_new_2PIC_SAT_D47_monthly = cov_raw_HadCM_new_2PIC_monthly_SAT.copy() # Copy covariance matrix to add uncertainty coming from the measurements
np.fill_diagonal(cov_prior_HadCM_new_2PIC_SST_D47_monthly, np.diagonal(cov_raw_HadCM_new_2PIC_monthly_SST) + HadCM_new_2PIC_calibration_variances_SST) # Add diagonal terms for measurement uncertainties (which have no covariance between models)
np.fill_diagonal(cov_prior_HadCM_new_2PIC_SAT_D47_monthly, np.diagonal(cov_raw_HadCM_new_2PIC_monthly_SAT) + HadCM_new_2PIC_calibration_variances_SAT) # Add diagonal terms for measurement uncertainties (which have no covariance between models)
cov_raw_HadCM_new_1056ppm_monthly_SST = np.cov(Lutetian_HadCM_new_1056ppm_model[[f"{month}_SST_D47" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_HadCM_new_1056ppm_monthly_SAT = np.cov(Lutetian_HadCM_new_1056ppm_model[[f"{month}_SAT_D47" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_HadCM_new_1056ppm_monthly_d18Ow = np.cov(Lutetian_HadCM_new_1056ppm_model[[f"{month}_SSS_d18Ow" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_HadCM_new_1056ppm_monthly_d18Oc = np.cov(Lutetian_HadCM_new_1056ppm_model[[f"{month}_d18Oc" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_prior_HadCM_new_1056ppm_SST_D47_monthly = cov_raw_HadCM_new_1056ppm_monthly_SST.copy() # Copy covariance matrix to add uncertainty coming from the measurements
cov_prior_HadCM_new_1056ppm_SAT_D47_monthly = cov_raw_HadCM_new_1056ppm_monthly_SAT.copy() # Copy covariance matrix to add uncertainty coming from the measurements
np.fill_diagonal(cov_prior_HadCM_new_1056ppm_SST_D47_monthly, np.diagonal(cov_raw_HadCM_new_1056ppm_monthly_SST) + HadCM_new_1056ppm_calibration_variances_SST) # Add diagonal terms for measurement uncertainties (which have no covariance between models)
np.fill_diagonal(cov_prior_HadCM_new_1056ppm_SAT_D47_monthly, np.diagonal(cov_raw_HadCM_new_1056ppm_monthly_SAT) + HadCM_new_1056ppm_calibration_variances_SAT) # Add diagonal terms for measurement uncertainties (which have no covariance between models)
cov_raw_HadCM_old_2PIC_monthly_SST = np.cov(Lutetian_HadCM_old_2PIC_model[[f"{month}_SST_D47" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_HadCM_old_2PIC_monthly_SAT = np.cov(Lutetian_HadCM_old_2PIC_model[[f"{month}_SAT_D47" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_HadCM_old_2PIC_monthly_d18Ow = np.cov(Lutetian_HadCM_old_2PIC_model[[f"{month}_SSS_d18Ow" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_HadCM_old_2PIC_monthly_d18Oc = np.cov(Lutetian_HadCM_old_2PIC_model[[f"{month}_d18Oc" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_prior_HadCM_old_2PIC_SST_D47_monthly = cov_raw_HadCM_old_2PIC_monthly_SST.copy() # Copy covariance matrix to add uncertainty coming from the measurements
cov_prior_HadCM_old_2PIC_SAT_D47_monthly = cov_raw_HadCM_old_2PIC_monthly_SAT.copy() # Copy covariance matrix to add uncertainty coming from the measurements
np.fill_diagonal(cov_prior_HadCM_old_2PIC_SST_D47_monthly, np.diagonal(cov_raw_HadCM_old_2PIC_monthly_SST) + HadCM_old_2PIC_calibration_variances_SST) # Add diagonal terms for measurement uncertainties (which have no covariance between models)
np.fill_diagonal(cov_prior_HadCM_old_2PIC_SAT_D47_monthly, np.diagonal(cov_raw_HadCM_old_2PIC_monthly_SAT) + HadCM_old_2PIC_calibration_variances_SAT) # Add diagonal terms for measurement uncertainties (which have no covariance between models)
cov_raw_HadCM_old_4PIC_monthly_SST = np.cov(Lutetian_HadCM_old_4PIC_model[[f"{month}_SST_D47" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_HadCM_old_4PIC_monthly_SAT = np.cov(Lutetian_HadCM_old_4PIC_model[[f"{month}_SAT_D47" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_HadCM_old_4PIC_monthly_d18Ow = np.cov(Lutetian_HadCM_old_4PIC_model[[f"{month}_SSS_d18Ow" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_raw_HadCM_old_4PIC_monthly_d18Oc = np.cov(Lutetian_HadCM_old_4PIC_model[[f"{month}_d18Oc" for month in months]].dropna(), rowvar = False) # Compute the covariance matrix for the raw data (without measurement uncertainty)
cov_prior_HadCM_old_4PIC_SST_D47_monthly = cov_raw_HadCM_old_4PIC_monthly_SST.copy() # Copy covariance matrix to add uncertainty coming from the measurements
cov_prior_HadCM_old_4PIC_SAT_D47_monthly = cov_raw_HadCM_old_4PIC_monthly_SAT.copy() # Copy covariance matrix to add uncertainty coming from the measurements
np.fill_diagonal(cov_prior_HadCM_old_4PIC_SST_D47_monthly, np.diagonal(cov_raw_HadCM_old_4PIC_monthly_SST) + HadCM_old_4PIC_calibration_variances_SST) # Add diagonal terms for measurement uncertainties (which have no covariance between models)
np.fill_diagonal(cov_prior_HadCM_old_4PIC_SAT_D47_monthly, np.diagonal(cov_raw_HadCM_old_4PIC_monthly_SAT) + HadCM_old_4PIC_calibration_variances_SAT) # Add diagonal terms for measurement uncertainties (which have no covariance between models)
# Store copy of original prior means to keep when later updating the prior
mu_prior_CESM_4PIC_SST_D47_monthly_original, cov_prior_CESM_4PIC_SST_D47_monthly_original = mu_prior_CESM_4PIC_SST_D47_monthly.copy(), cov_prior_CESM_4PIC_SST_D47_monthly.copy()
mu_prior_CESM_4PIC_SAT_D47_monthly_original, cov_prior_CESM_4PIC_SAT_D47_monthly_original = mu_prior_CESM_4PIC_SAT_D47_monthly.copy(), cov_prior_CESM_4PIC_SAT_D47_monthly.copy()
mu_prior_CESM_4PIC_SSS_d18Ow_monthly_original, cov_prior_CESM_4PIC_SSS_d18Ow_monthly_original = mu_prior_CESM_4PIC_SSS_d18Ow_monthly.copy(), cov_raw_CESM_4PIC_monthly_d18Ow.copy()
mu_prior_CESM_4PIC_d18Oc_monthly_original, cov_prior_CESM_4PIC_d18Oc_monthly_original = mu_prior_CESM_4PIC_d18Oc_monthly.copy(), cov_raw_CESM_4PIC_monthly_d18Oc.copy()
mu_prior_CESM_2PIC_SST_D47_monthly_original, cov_prior_CESM_2PIC_SST_D47_monthly_original = mu_prior_CESM_2PIC_SST_D47_monthly.copy(), cov_prior_CESM_2PIC_SST_D47_monthly.copy()
mu_prior_CESM_2PIC_SAT_D47_monthly_original, cov_prior_CESM_2PIC_SAT_D47_monthly_original = mu_prior_CESM_2PIC_SAT_D47_monthly.copy(), cov_prior_CESM_2PIC_SAT_D47_monthly.copy()
mu_prior_CESM_2PIC_SSS_d18Ow_monthly_original, cov_prior_CESM_2PIC_SSS_d18Ow_monthly_original = mu_prior_CESM_2PIC_SSS_d18Ow_monthly.copy(), cov_raw_CESM_2PIC_monthly_d18Ow.copy()
mu_prior_CESM_2PIC_d18Oc_monthly_original, cov_prior_CESM_2PIC_d18Oc_monthly_original = mu_prior_CESM_2PIC_d18Oc_monthly.copy(), cov_raw_CESM_2PIC_monthly_d18Oc.copy()
mu_prior_HadCM_new_1PIC_SST_D47_monthly_original, cov_prior_HadCM_new_1PIC_SST_D47_monthly_original = mu_prior_HadCM_new_1PIC_SST_D47_monthly.copy(), cov_prior_HadCM_new_1PIC_SST_D47_monthly.copy()
mu_prior_HadCM_new_1PIC_SAT_D47_monthly_original, cov_prior_HadCM_new_1PIC_SAT_D47_monthly_original = mu_prior_HadCM_new_1PIC_SAT_D47_monthly.copy(), cov_prior_HadCM_new_1PIC_SAT_D47_monthly.copy()
mu_prior_HadCM_new_1PIC_SSS_d18Ow_monthly_original, cov_prior_HadCM_new_1PIC_SSS_d18Ow_monthly_original = mu_prior_HadCM_new_1PIC_SSS_d18Ow_monthly.copy(), cov_raw_HadCM_new_1PIC_monthly_d18Ow.copy()
mu_prior_HadCM_new_1PIC_d18Oc_monthly_original, cov_prior_HadCM_new_1PIC_d18Oc_monthly_original = mu_prior_HadCM_new_1PIC_d18Oc_monthly.copy(), cov_raw_HadCM_new_1PIC_monthly_d18Oc.copy()
mu_prior_HadCM_new_2PIC_SST_D47_monthly_original, cov_prior_HadCM_new_2PIC_SST_D47_monthly_original = mu_prior_HadCM_new_2PIC_SST_D47_monthly.copy(), cov_prior_HadCM_new_2PIC_SST_D47_monthly.copy()
mu_prior_HadCM_new_2PIC_SAT_D47_monthly_original, cov_prior_HadCM_new_2PIC_SAT_D47_monthly_original = mu_prior_HadCM_new_2PIC_SAT_D47_monthly.copy(), cov_prior_HadCM_new_2PIC_SAT_D47_monthly.copy()
mu_prior_HadCM_new_2PIC_SSS_d18Ow_monthly_original, cov_prior_HadCM_new_2PIC_SSS_d18Ow_monthly_original = mu_prior_HadCM_new_2PIC_SSS_d18Ow_monthly.copy(), cov_raw_HadCM_new_2PIC_monthly_d18Ow.copy()
mu_prior_HadCM_new_2PIC_d18Oc_monthly_original, cov_prior_HadCM_new_2PIC_d18Oc_monthly_original = mu_prior_HadCM_new_2PIC_d18Oc_monthly.copy(), cov_raw_HadCM_new_2PIC_monthly_d18Oc.copy()
mu_prior_HadCM_new_1056ppm_SST_D47_monthly_original, cov_prior_HadCM_new_1056ppm_SST_D47_monthly_original = mu_prior_HadCM_new_1056ppm_SST_D47_monthly.copy(), cov_prior_HadCM_new_1056ppm_SST_D47_monthly.copy()
mu_prior_HadCM_new_1056ppm_SAT_D47_monthly_original, cov_prior_HadCM_new_1056ppm_SAT_D47_monthly_original = mu_prior_HadCM_new_1056ppm_SAT_D47_monthly.copy(), cov_prior_HadCM_new_1056ppm_SAT_D47_monthly.copy()
mu_prior_HadCM_new_1056ppm_SSS_d18Ow_monthly_original, cov_prior_HadCM_new_1056ppm_SSS_d18Ow_monthly_original = mu_prior_HadCM_new_1056ppm_SSS_d18Ow_monthly.copy(), cov_raw_HadCM_new_1056ppm_monthly_d18Ow.copy()
mu_prior_HadCM_new_1056ppm_d18Oc_monthly_original, cov_prior_HadCM_new_1056ppm_d18Oc_monthly_original = mu_prior_HadCM_new_1056ppm_d18Oc_monthly.copy(), cov_raw_HadCM_new_1056ppm_monthly_d18Oc.copy()
mu_prior_HadCM_old_2PIC_SST_D47_monthly_original, cov_prior_HadCM_old_2PIC_SST_D47_monthly_original = mu_prior_HadCM_old_2PIC_SST_D47_monthly.copy(), cov_prior_HadCM_old_2PIC_SST_D47_monthly.copy()
mu_prior_HadCM_old_2PIC_SAT_D47_monthly_original, cov_prior_HadCM_old_2PIC_SAT_D47_monthly_original = mu_prior_HadCM_old_2PIC_SAT_D47_monthly.copy(), cov_prior_HadCM_old_2PIC_SAT_D47_monthly.copy()
mu_prior_HadCM_old_2PIC_SSS_d18Ow_monthly_original, cov_prior_HadCM_old_2PIC_SSS_d18Ow_monthly_original = mu_prior_HadCM_old_2PIC_SSS_d18Ow_monthly.copy(), cov_raw_HadCM_old_2PIC_monthly_d18Ow.copy()
mu_prior_HadCM_old_2PIC_d18Oc_monthly_original, cov_prior_HadCM_old_2PIC_d18Oc_monthly_original = mu_prior_HadCM_old_2PIC_d18Oc_monthly.copy(), cov_raw_HadCM_old_2PIC_monthly_d18Oc.copy()
mu_prior_HadCM_old_4PIC_SST_D47_monthly_original, cov_prior_HadCM_old_4PIC_SST_D47_monthly_original = mu_prior_HadCM_old_4PIC_SST_D47_monthly.copy(), cov_prior_HadCM_old_4PIC_SST_D47_monthly.copy()
mu_prior_HadCM_old_4PIC_SAT_D47_monthly_original, cov_prior_HadCM_old_4PIC_SAT_D47_monthly_original = mu_prior_HadCM_old_4PIC_SAT_D47_monthly.copy(), cov_prior_HadCM_old_4PIC_SAT_D47_monthly.copy()
mu_prior_HadCM_old_4PIC_SSS_d18Ow_monthly_original, cov_prior_HadCM_old_4PIC_SSS_d18Ow_monthly_original = mu_prior_HadCM_old_4PIC_SSS_d18Ow_monthly.copy(), cov_raw_HadCM_old_4PIC_monthly_d18Ow.copy()
mu_prior_HadCM_old_4PIC_d18Oc_monthly_original, cov_prior_HadCM_old_4PIC_d18Oc_monthly_original = mu_prior_HadCM_old_4PIC_d18Oc_monthly.copy(), cov_raw_HadCM_old_4PIC_monthly_d18Oc.copy()
# Extract the standard deviations (uncertainty) from the covariance matrix
std_prior_CESM_4PIC_SST_D47_monthly = np.sqrt(np.diag(cov_prior_CESM_4PIC_SST_D47_monthly))
std_prior_CESM_4PIC_SAT_D47_monthly = np.sqrt(np.diag(cov_prior_CESM_4PIC_SAT_D47_monthly))
std_prior_CESM_4PIC_SSS_d18Ow_monthly = np.sqrt(np.diag(cov_raw_CESM_4PIC_monthly_d18Ow))
std_prior_CESM_4PIC_d18Oc_monthly = np.sqrt(np.diag(cov_raw_CESM_4PIC_monthly_d18Oc))
std_prior_CESM_2PIC_SST_D47_monthly = np.sqrt(np.diag(cov_prior_CESM_2PIC_SST_D47_monthly))
std_prior_CESM_2PIC_SAT_D47_monthly = np.sqrt(np.diag(cov_prior_CESM_2PIC_SAT_D47_monthly))
std_prior_CESM_2PIC_SSS_d18Ow_monthly = np.sqrt(np.diag(cov_raw_CESM_2PIC_monthly_d18Ow))
std_prior_CESM_2PIC_d18Oc_monthly = np.sqrt(np.diag(cov_raw_CESM_2PIC_monthly_d18Oc))
std_prior_HadCM_new_1PIC_SST_D47_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_1PIC_SST_D47_monthly))
std_prior_HadCM_new_1PIC_SAT_D47_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_1PIC_SAT_D47_monthly))
std_prior_HadCM_new_1PIC_SSS_d18Ow_monthly = np.sqrt(np.diag(cov_raw_HadCM_new_1PIC_monthly_d18Ow))
std_prior_HadCM_new_1PIC_d18Oc_monthly = np.sqrt(np.diag(cov_raw_HadCM_new_1PIC_monthly_d18Oc))
std_prior_HadCM_new_2PIC_SST_D47_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_2PIC_SST_D47_monthly))
std_prior_HadCM_new_2PIC_SAT_D47_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_2PIC_SAT_D47_monthly))
std_prior_HadCM_new_2PIC_SSS_d18Ow_monthly = np.sqrt(np.diag(cov_raw_HadCM_new_2PIC_monthly_d18Ow))
std_prior_HadCM_new_2PIC_d18Oc_monthly = np.sqrt(np.diag(cov_raw_HadCM_new_2PIC_monthly_d18Oc))
std_prior_HadCM_new_1056ppm_SST_D47_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_1056ppm_SST_D47_monthly))
std_prior_HadCM_new_1056ppm_SAT_D47_monthly = np.sqrt(np.diag(cov_prior_HadCM_new_1056ppm_SAT_D47_monthly))
std_prior_HadCM_new_1056ppm_SSS_d18Ow_monthly = np.sqrt(np.diag(cov_raw_HadCM_new_1056ppm_monthly_d18Ow))
std_prior_HadCM_new_1056ppm_d18Oc_monthly = np.sqrt(np.diag(cov_raw_HadCM_new_1056ppm_monthly_d18Oc))
std_prior_HadCM_old_2PIC_SST_D47_monthly = np.sqrt(np.diag(cov_prior_HadCM_old_2PIC_SST_D47_monthly))
std_prior_HadCM_old_2PIC_SAT_D47_monthly = np.sqrt(np.diag(cov_prior_HadCM_old_2PIC_SAT_D47_monthly))
std_prior_HadCM_old_2PIC_SSS_d18Ow_monthly = np.sqrt(np.diag(cov_raw_HadCM_old_2PIC_monthly_d18Ow))
std_prior_HadCM_old_2PIC_d18Oc_monthly = np.sqrt(np.diag(cov_raw_HadCM_old_2PIC_monthly_d18Oc))
std_prior_HadCM_old_4PIC_SST_D47_monthly = np.sqrt(np.diag(cov_prior_HadCM_old_4PIC_SST_D47_monthly))
std_prior_HadCM_old_4PIC_SAT_D47_monthly = np.sqrt(np.diag(cov_prior_HadCM_old_4PIC_SAT_D47_monthly))
std_prior_HadCM_old_4PIC_SSS_d18Ow_monthly = np.sqrt(np.diag(cov_raw_HadCM_old_4PIC_monthly_d18Ow))
std_prior_HadCM_old_4PIC_d18Oc_monthly = np.sqrt(np.diag(cov_raw_HadCM_old_4PIC_monthly_d18Oc))
# Print some the results as a check
print("Prior D47 estimates from SST in CESM model with 4x preindustrial pCO2 (weighted mean):")
print(mu_prior_CESM_4PIC_SST_D47_monthly)
print("Prior D47 estimates from SST in CESM model with 2x preindustrial pCO2 (weighted mean):")
print(mu_prior_CESM_2PIC_SST_D47_monthly)
print("Prior D47 estimates from SST in CESM model with 4x preindustrial pCO2 (weighted covariance matrix):")
print(std_prior_CESM_4PIC_SST_D47_monthly)
print("Prior D47 estimates from SST in CESM model with 2x preindustrial pCO2 (weighted covariance matrix):")
print(std_prior_CESM_2PIC_SST_D47_monthly)
print("Prior D47 estimates from SAT in CESM model with 4x preindustrial pCO2 (weighted mean):")
print(mu_prior_CESM_4PIC_SAT_D47_monthly)
print("Prior D47 estimates from SAT in CESM model with 2x preindustrial pCO2 (weighted mean):")
print(mu_prior_CESM_2PIC_SAT_D47_monthly)
print("Prior D47 estimates from SAT in CESM model with 4x preindustrial pCO2 (weighted covariance matrix):")
print(std_prior_CESM_4PIC_SAT_D47_monthly)
print("Prior D47 estimates from SAT in CESM model with 2x preindustrial pCO2 (weighted covariance matrix):")
print(std_prior_CESM_2PIC_SAT_D47_monthly)
print("Prior d18Ow estimates from SSS in CESM model with 4x preindustrial pCO2 (weighted mean):")
print(mu_prior_CESM_4PIC_SSS_d18Ow_monthly)
print("Prior d18Ow estimates from SSS in CESM model with 2x preindustrial pCO2 (weighted mean):")
print(mu_prior_CESM_2PIC_SSS_d18Ow_monthly)
print("Prior d18Ow estimates from SSS in CESM model with 4x preindustrial pCO2 (weighted covariance matrix):")
print(std_prior_CESM_4PIC_SSS_d18Ow_monthly)
print("Prior d18Ow estimates from SSS in CESM model with 2x preindustrial pCO2 (weighted covariance matrix):")
print(std_prior_CESM_2PIC_SSS_d18Ow_monthly)
print("Prior d18Oc estimates from SST and d18Ow in CESM model with 4x preindustrial pCO2 (weighted mean):")
print(mu_prior_CESM_4PIC_d18Oc_monthly)
print("Prior d18Oc estimates from SST and d18Ow in CESM model with 2x preindustrial pCO2 (weighted mean):")
print(mu_prior_CESM_2PIC_d18Oc_monthly)
print("Prior d18Oc estimates from SST and d18Ow in CESM model with 4x preindustrial pCO2 (weighted covariance matrix):")
print(std_prior_CESM_4PIC_d18Oc_monthly)
print("Prior d18Oc estimates from SST and d18Ow in CESM model with 2x preindustrial pCO2 (weighted covariance matrix):")
print(std_prior_CESM_2PIC_d18Oc_monthly)
Prior D47 estimates from SST in CESM model with 4x preindustrial pCO2 (weighted mean): [0.59656789 0.59858139 0.59867924 0.59638204 0.58858685 0.57705811 0.56727922 0.56351195 0.5670409 0.57510508 0.58376364 0.59171077] Prior D47 estimates from SST in CESM model with 2x preindustrial pCO2 (weighted mean): [0.60489442 0.60666426 0.60683094 0.60417118 0.59618643 0.58512465 0.5755485 0.57189757 0.57548974 0.58366672 0.59236182 0.60038379] Prior D47 estimates from SST in CESM model with 4x preindustrial pCO2 (weighted covariance matrix): [0.00890411 0.00944467 0.00936157 0.00859554 0.00739686 0.00653869 0.00575527 0.00534817 0.00493985 0.00482531 0.00621776 0.00782822] Prior D47 estimates from SST in CESM model with 2x preindustrial pCO2 (weighted covariance matrix): [0.01009378 0.01057793 0.01042161 0.00955301 0.00826056 0.00738042 0.0066458 0.00598658 0.00544544 0.0055813 0.00709986 0.00884544] Prior D47 estimates from SAT in CESM model with 4x preindustrial pCO2 (weighted mean): [0.62006985 0.61787124 0.61269573 0.60374682 0.58703137 0.57294061 0.56290407 0.56283341 0.57307851 0.59111554 0.60696862 0.61709809] Prior D47 estimates from SAT in CESM model with 2x preindustrial pCO2 (weighted mean): [0.63053005 0.62879279 0.62393577 0.61368013 0.59859233 0.5867432 0.57737842 0.57609754 0.58529981 0.60308352 0.61883373 0.62866658] Prior D47 estimates from SAT in CESM model with 4x preindustrial pCO2 (weighted covariance matrix): [0.01142741 0.01018869 0.0090148 0.00801557 0.00738831 0.00779214 0.00785649 0.00725533 0.00718243 0.00905268 0.01135674 0.01208698] Prior D47 estimates from SAT in CESM model with 2x preindustrial pCO2 (weighted covariance matrix): [0.01208732 0.0110329 0.00996397 0.00848212 0.00760235 0.00785875 0.00842843 0.00790733 0.0080588 0.01021703 0.01233193 0.013147 ] Prior d18Ow estimates from SSS in CESM model with 4x preindustrial pCO2 (weighted mean): [0.15012888 0.14789931 0.14304506 0.13812488 0.13628413 0.13603111 0.13019769 0.12741946 0.12790254 0.13567087 0.14471762 0.15102158] Prior d18Ow estimates from SSS in CESM model with 2x preindustrial pCO2 (weighted mean): [0.17535131 0.16860723 0.16122267 0.15074699 0.14675776 0.14626297 0.14379877 0.1478799 0.15903551 0.1703924 0.17741777 0.1799819 ] Prior d18Ow estimates from SSS in CESM model with 4x preindustrial pCO2 (weighted covariance matrix): [0.82621873 0.81838544 0.81441585 0.81562978 0.82277265 0.83136673 0.84163147 0.85144349 0.85933502 0.86079046 0.85069356 0.83659413] Prior d18Ow estimates from SSS in CESM model with 2x preindustrial pCO2 (weighted covariance matrix): [0.78365866 0.77611692 0.77221433 0.7756884 0.78626843 0.79651165 0.80712123 0.81866035 0.82756578 0.82843509 0.81688634 0.79756155] Prior d18Oc estimates from SST and d18Ow in CESM model with 4x preindustrial pCO2 (weighted mean): [-0.87134431 -0.71613404 -0.7139883 -0.89894578 -1.51047705 -2.43504627 -3.25136303 -3.57317763 -3.27234184 -2.5945588 -1.88634864 -1.25084057] Prior d18Oc estimates from SST and d18Ow in CESM model with 2x preindustrial pCO2 (weighted mean): [-0.20804548 -0.07873241 -0.07509482 -0.29063799 -0.90690032 -1.77413891 -2.55085312 -2.84797432 -2.54024627 -1.8689654 -1.17633926 -0.55155968] Prior d18Oc estimates from SST and d18Ow in CESM model with 4x preindustrial pCO2 (weighted covariance matrix): [0.43074162 0.4079074 0.39792762 0.39889866 0.41067086 0.41700845 0.43048772 0.48872905 0.56171093 0.58936283 0.51749387 0.46825537] Prior d18Oc estimates from SST and d18Ow in CESM model with 2x preindustrial pCO2 (weighted covariance matrix): [0.40225003 0.393072 0.38290499 0.36843204 0.36587289 0.37604721 0.38016149 0.44783066 0.51482087 0.52320248 0.45863081 0.42027637]
Plot the monthly prior for model SST- and SAT-derived D47 values, model SSS-derived carbonate d18O values and precipitation with propagated uncertainty¶
In [38]:
# Plot monthly prior distribution
fig, axes = plt.subplots(4, 7, figsize=(20, 10), sharey="row", sharex="col") # Adjust the figure to have 2x2 grid
# Start with priors for CESM model with 4x pre-industrial CO2
# Plot the prior distribution for SST
axes[0, 0].plot(months_scale, mu_prior_CESM_4PIC_SST_D47_monthly, label='Prior SST Mean', color='b', marker='o')
axes[0, 0].fill_between(months_scale,
mu_prior_CESM_4PIC_SST_D47_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SST_D47_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
mu_prior_CESM_4PIC_SST_D47_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SST_D47_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
axes[0, 0].set_xticks(months_scale)
axes[0, 0].set_xticklabels(month_names, rotation=45, ha="right")
axes[0, 0].set_title('CESM\n4x preindustrial pCO2\nSST D47 values')
axes[0, 0].set_xlabel('Month')
axes[0, 0].set_ylabel('D47 value')
# axes[0, 0].legend()
axes[0, 0].grid(True)
# Plot the prior distribution for SAT
axes[1, 0].plot(months_scale, mu_prior_CESM_4PIC_SAT_D47_monthly, label='Prior SAT Mean', color='r', marker='o')
axes[1, 0].fill_between(months_scale,
mu_prior_CESM_4PIC_SAT_D47_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SAT_D47_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
mu_prior_CESM_4PIC_SAT_D47_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SAT_D47_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
axes[1, 0].set_xticks(months_scale)
axes[1, 0].set_xticklabels(month_names, rotation=45, ha="right")
axes[1, 0].set_title('SAT D47 values')
axes[1, 0].set_xlabel('Month')
axes[1, 0].set_ylabel('D47 value')
# axes[1, 0].legend()
axes[1, 0].grid(True)
# Plot the prior distribution for d18Oc
axes[2, 0].plot(months_scale, mu_prior_CESM_4PIC_d18Oc_monthly, label='Prior d18Oc Mean', color='purple', marker='o')
axes[2, 0].fill_between(months_scale,
mu_prior_CESM_4PIC_d18Oc_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_d18Oc_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
mu_prior_CESM_4PIC_d18Oc_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_d18Oc_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
color='purple', alpha=0.2, label='95% Confidence Interval')
axes[2, 0].set_xticks(months_scale)
axes[2, 0].set_xticklabels(month_names, rotation=45, ha="right")
axes[2, 0].set_title('d18Oc values')
axes[2, 0].set_xlabel('Month')
axes[2, 0].set_ylabel('d18Oc value')
# axes[2, 0].legend()
axes[2, 0].grid(True)
# Plot the prior distribution for precipitation
axes[3, 0].plot(months_scale, mu_prior_CESM_4PIC_precip_monthly, label='Prior Precipitation Mean', color='teal', marker='o')
axes[3, 0].fill_between(months_scale,
mu_prior_CESM_4PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_precip_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
mu_prior_CESM_4PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_precip_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
color='teal', alpha=0.2, label='95% Confidence Interval')
axes[3, 0].set_xticks(months_scale)
axes[3, 0].set_xticklabels(month_names, rotation=45, ha="right")
axes[3, 0].set_title('Precipitation values')
axes[3, 0].set_xlabel('Month')
axes[3, 0].set_ylabel('Precipitation (mm/day)')
# axes[3, 0].legend()
axes[3, 0].grid(True)
# Now for priors for CESM model with 2x pre-industrial CO2
# Plot the prior distribution for SST
axes[0, 1].plot(months_scale, mu_prior_CESM_2PIC_SST_D47_monthly, label='Prior SST Mean', color='b', marker='o')
axes[0, 1].fill_between(months_scale,
mu_prior_CESM_2PIC_SST_D47_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SST_D47_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_SST_D47_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SST_D47_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
axes[0, 1].set_xticks(months_scale)
axes[0, 1].set_xticklabels(month_names, rotation=45, ha="right")
axes[0, 1].set_title('CESM\n2x preindustrial pCO2\nSST D47 values')
axes[0, 1].set_xlabel('Month')
axes[0, 1].set_ylabel('D47 value')
# axes[0, 1].legend()
axes[0, 1].grid(True)
# Plot the prior distribution for SAT
axes[1, 1].plot(months_scale, mu_prior_CESM_2PIC_SAT_D47_monthly, label='Prior SAT Mean', color='r', marker='o')
axes[1, 1].fill_between(months_scale,
mu_prior_CESM_2PIC_SAT_D47_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SAT_D47_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_SAT_D47_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SAT_D47_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
axes[1, 1].set_xticks(months_scale)
axes[1, 1].set_xticklabels(month_names, rotation=45, ha="right")
axes[1, 1].set_title('SAT D47 values')
axes[1, 1].set_xlabel('Month')
axes[1, 1].set_ylabel('D47 value')
# axes[1, 1].legend()
axes[1, 1].grid(True)
# Plot the prior distribution for d18Oc
axes[2, 1].plot(months_scale, mu_prior_CESM_2PIC_d18Oc_monthly, label='Prior d18Oc Mean', color='purple', marker='o')
axes[2, 1].fill_between(months_scale,
mu_prior_CESM_2PIC_d18Oc_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_d18Oc_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_d18Oc_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_d18Oc_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
color='purple', alpha=0.2, label='95% Confidence Interval')
axes[2, 1].set_xticks(months_scale)
axes[2, 1].set_xticklabels(month_names, rotation=45, ha="right")
axes[2, 1].set_title('d18Oc values')
axes[2, 1].set_xlabel('Month')
axes[2, 1].set_ylabel('d18Oc value')
# axes[2, 1].legend()
axes[2, 1].grid(True)
# Plot the prior distribution for precipitation
axes[3, 1].plot(months_scale, mu_prior_CESM_2PIC_precip_monthly, label='Prior Precipitation Mean', color='teal', marker='o')
axes[3, 1].fill_between(months_scale,
mu_prior_CESM_2PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_precip_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_precip_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
color='teal', alpha=0.2, label='95% Confidence Interval')
axes[3, 1].set_xticks(months_scale)
axes[3, 1].set_xticklabels(month_names, rotation=45, ha="right")
axes[3, 1].set_title('Precipitation values')
axes[3, 1].set_xlabel('Month')
axes[3, 1].set_ylabel('Precipitation (mm/day)')
# axes[3, 1].legend()
axes[3, 1].grid(True)
# Now for priors for HadCM model with 1x pre-industrial CO2
# Plot the prior distribution for SST
axes[0, 2].plot(months_scale, mu_prior_HadCM_new_1PIC_SST_D47_monthly, label='Prior SST Mean', color='b', marker='o')
axes[0, 2].fill_between(months_scale,
mu_prior_HadCM_new_1PIC_SST_D47_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SST_D47_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
mu_prior_HadCM_new_1PIC_SST_D47_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SST_D47_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
axes[0, 2].set_xticks(months_scale)
axes[0, 2].set_xticklabels(month_names, rotation=45, ha="right")
axes[0, 2].set_title('HadCM (new)\n1x preindustrial pCO2\nSST D47 values')
axes[0, 2].set_xlabel('Month')
axes[0, 2].set_ylabel('D47 value')
# axes[0, 2].legend()
axes[0, 2].grid(True)
# Plot the prior distribution for SAT
axes[1, 2].plot(months_scale, mu_prior_HadCM_new_1PIC_SAT_D47_monthly, label='Prior SAT Mean', color='r', marker='o')
axes[1, 2].fill_between(months_scale,
mu_prior_HadCM_new_1PIC_SAT_D47_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SAT_D47_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
mu_prior_HadCM_new_1PIC_SAT_D47_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SAT_D47_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
axes[1, 2].set_xticks(months_scale)
axes[1, 2].set_xticklabels(month_names, rotation=45, ha="right")
axes[1, 2].set_title('SAT D47 values')
axes[1, 2].set_xlabel('Month')
axes[1, 2].set_ylabel('D47 value')
# axes[1, 2].legend()
axes[1, 2].grid(True)
# Plot the prior distribution for d18Oc
axes[2, 2].plot(months_scale, mu_prior_HadCM_new_1PIC_d18Oc_monthly, label='Prior d18Oc Mean', color='purple', marker='o')
axes[2, 2].fill_between(months_scale,
mu_prior_HadCM_new_1PIC_d18Oc_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_d18Oc_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
mu_prior_HadCM_new_1PIC_d18Oc_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_d18Oc_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
color='purple', alpha=0.2, label='95% Confidence Interval')
axes[2, 2].set_xticks(months_scale)
axes[2, 2].set_xticklabels(month_names, rotation=45, ha="right")
axes[2, 2].set_title('d18Oc values')
axes[2, 2].set_xlabel('Month')
axes[2, 2].set_ylabel('d18Oc value')
# axes[2, 2].legend()
axes[2, 2].grid(True)
# Plot the prior distribution for precipitation
axes[3, 2].plot(months_scale, mu_prior_HadCM_new_1PIC_precip_monthly, label='Prior Precipitation Mean', color='teal', marker='o')
axes[3, 2].fill_between(months_scale,
mu_prior_HadCM_new_1PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_precip_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
mu_prior_HadCM_new_1PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_precip_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
color='teal', alpha=0.2, label='95% Confidence Interval')
axes[3, 2].set_xticks(months_scale)
axes[3, 2].set_xticklabels(month_names, rotation=45, ha="right")
axes[3, 2].set_title('Precipitation values')
axes[3, 2].set_xlabel('Month')
axes[3, 2].set_ylabel('Precipitation (mm/day)')
# axes[3, 2].legend()
axes[3, 2].grid(True)
# Now for priors for HadCM model with 2x pre-industrial CO2
# Plot the prior distribution for SST
axes[0, 3].plot(months_scale, mu_prior_HadCM_new_2PIC_SST_D47_monthly, label='Prior SST Mean', color='b', marker='o')
axes[0, 3].fill_between(months_scale,
mu_prior_HadCM_new_2PIC_SST_D47_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SST_D47_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
mu_prior_HadCM_new_2PIC_SST_D47_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SST_D47_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
axes[0, 3].set_xticks(months_scale)
axes[0, 3].set_xticklabels(month_names, rotation=45, ha="right")
axes[0, 3].set_title('HadCM (new)\n2x preindustrial pCO2\nSST D47 values')
axes[0, 3].set_xlabel('Month')
axes[0, 3].set_ylabel('D47 value')
# axes[0, 3].legend()
axes[0, 3].grid(True)
# Plot the prior distribution for SAT
axes[1, 3].plot(months_scale, mu_prior_HadCM_new_2PIC_SAT_D47_monthly, label='Prior SAT Mean', color='r', marker='o')
axes[1, 3].fill_between(months_scale,
mu_prior_HadCM_new_2PIC_SAT_D47_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SAT_D47_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
mu_prior_HadCM_new_2PIC_SAT_D47_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SAT_D47_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
axes[1, 3].set_xticks(months_scale)
axes[1, 3].set_xticklabels(month_names, rotation=45, ha="right")
axes[1, 3].set_title('SAT D47 values')
axes[1, 3].set_xlabel('Month')
axes[1, 3].set_ylabel('D47 value')
# axes[1, 3].legend()
axes[1, 3].grid(True)
# Plot the prior distribution for d18Oc
axes[2, 3].plot(months_scale, mu_prior_HadCM_new_2PIC_d18Oc_monthly, label='Prior d18Oc Mean', color='purple', marker='o')
axes[2, 3].fill_between(months_scale,
mu_prior_HadCM_new_2PIC_d18Oc_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_d18Oc_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
mu_prior_HadCM_new_2PIC_d18Oc_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_d18Oc_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
color='purple', alpha=0.2, label='95% Confidence Interval')
axes[2, 3].set_xticks(months_scale)
axes[2, 3].set_xticklabels(month_names, rotation=45, ha="right")
axes[2, 3].set_title('d18Oc values')
axes[2, 3].set_xlabel('Month')
axes[2, 3].set_ylabel('d18Oc value')
# axes[2, 3].legend()
axes[2, 3].grid(True)
# Plot the prior distribution for precipitation
axes[3, 3].plot(months_scale, mu_prior_HadCM_new_2PIC_precip_monthly, label='Prior Precipitation Mean', color='teal', marker='o')
axes[3, 3].fill_between(months_scale,
mu_prior_HadCM_new_2PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_precip_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
mu_prior_HadCM_new_2PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_precip_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
color='teal', alpha=0.2, label='95% Confidence Interval')
axes[3, 3].set_xticks(months_scale)
axes[3, 3].set_xticklabels(month_names, rotation=45, ha="right")
axes[3, 3].set_title('Precipitation values')
axes[3, 3].set_xlabel('Month')
axes[3, 3].set_ylabel('Precipitation (mm/day)')
# axes[3, 3].legend()
axes[3, 3].grid(True)
# Now for priors for HadCM model with 1056 ppm CO2
# Plot the prior distribution for SST
axes[0, 4].plot(months_scale, mu_prior_HadCM_new_1056ppm_SST_D47_monthly, label='Prior SST Mean', color='b', marker='o')
axes[0, 4].fill_between(months_scale,
mu_prior_HadCM_new_1056ppm_SST_D47_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SST_D47_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
mu_prior_HadCM_new_1056ppm_SST_D47_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SST_D47_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
axes[0, 4].set_xticks(months_scale)
axes[0, 4].set_xticklabels(month_names, rotation=45, ha="right")
axes[0, 4].set_title('HadCM (new)\n1056 ppm pCO2\nSST D47 values')
axes[0, 4].set_xlabel('Month')
axes[0, 4].set_ylabel('D47 value')
# axes[0, 4].legend()
axes[0, 4].grid(True)
# Plot the prior distribution for SAT
axes[1, 4].plot(months_scale, mu_prior_HadCM_new_1056ppm_SAT_D47_monthly, label='Prior SAT Mean', color='r', marker='o')
axes[1, 4].fill_between(months_scale,
mu_prior_HadCM_new_1056ppm_SAT_D47_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SAT_D47_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
mu_prior_HadCM_new_1056ppm_SAT_D47_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SAT_D47_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
axes[1, 4].set_xticks(months_scale)
axes[1, 4].set_xticklabels(month_names, rotation=45, ha="right")
axes[1, 4].set_title('SAT D47 values')
axes[1, 4].set_xlabel('Month')
axes[1, 4].set_ylabel('D47 value')
# axes[1, 4].legend()
axes[1, 4].grid(True)
# Plot the prior distribution for d18Oc
axes[2, 4].plot(months_scale, mu_prior_HadCM_new_1056ppm_d18Oc_monthly, label='Prior d18Oc Mean', color='purple', marker='o')
axes[2, 4].fill_between(months_scale,
mu_prior_HadCM_new_1056ppm_d18Oc_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_d18Oc_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
mu_prior_HadCM_new_1056ppm_d18Oc_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_d18Oc_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
color='purple', alpha=0.2, label='95% Confidence Interval')
axes[2, 4].set_xticks(months_scale)
axes[2, 4].set_xticklabels(month_names, rotation=45, ha="right")
axes[2, 4].set_title('d18Oc values')
axes[2, 4].set_xlabel('Month')
axes[2, 4].set_ylabel('d18Oc value')
# axes[2, 4].legend()
axes[2, 4].grid(True)
# Plot the prior distribution for precipitation
axes[3, 4].plot(months_scale, mu_prior_HadCM_new_1056ppm_precip_monthly, label='Prior Precipitation Mean', color='teal', marker='o')
axes[3, 4].fill_between(months_scale,
mu_prior_HadCM_new_1056ppm_precip_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_precip_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
mu_prior_HadCM_new_1056ppm_precip_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_precip_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
color='teal', alpha=0.2, label='95% Confidence Interval')
axes[3, 4].set_xticks(months_scale)
axes[3, 4].set_xticklabels(month_names, rotation=45, ha="right")
axes[3, 4].set_title('Precipitation values')
axes[3, 4].set_xlabel('Month')
axes[3, 4].set_ylabel('Precipitation (mm/day)')
# axes[3, 4].legend()
axes[3, 4].grid(True)
# Now for priors for old HadCM model with 2x preindustrial CO2
# Plot the prior distribution for SST
axes[0, 5].plot(months_scale, mu_prior_HadCM_old_2PIC_SST_D47_monthly, label='Prior SST Mean', color='b', marker='o')
axes[0, 5].fill_between(months_scale,
mu_prior_HadCM_old_2PIC_SST_D47_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SST_D47_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
mu_prior_HadCM_old_2PIC_SST_D47_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SST_D47_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
axes[0, 5].set_xticks(months_scale)
axes[0, 5].set_xticklabels(month_names, rotation=45, ha="right")
axes[0, 5].set_title('HadCM (old)\n2x preindustrial pCO2\nSST D47 values')
axes[0, 5].set_xlabel('Month')
axes[0, 5].set_ylabel('D47 value')
# axes[0, 5].legend()
axes[0, 5].grid(True)
# Plot the prior distribution for SAT
axes[1, 5].plot(months_scale, mu_prior_HadCM_old_2PIC_SAT_D47_monthly, label='Prior SAT Mean', color='r', marker='o')
axes[1, 5].fill_between(months_scale,
mu_prior_HadCM_old_2PIC_SAT_D47_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SAT_D47_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
mu_prior_HadCM_old_2PIC_SAT_D47_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SAT_D47_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
axes[1, 5].set_xticks(months_scale)
axes[1, 5].set_xticklabels(month_names, rotation=45, ha="right")
axes[1, 5].set_title('SAT D47 values')
axes[1, 5].set_xlabel('Month')
axes[1, 5].set_ylabel('D47 value')
# axes[1, 5].legend()
axes[1, 5].grid(True)
# Plot the prior distribution for d18Oc
axes[2, 5].plot(months_scale, mu_prior_HadCM_old_2PIC_d18Oc_monthly, label='Prior d18Oc Mean', color='purple', marker='o')
axes[2, 5].fill_between(months_scale,
mu_prior_HadCM_old_2PIC_d18Oc_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_d18Oc_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
mu_prior_HadCM_old_2PIC_d18Oc_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_d18Oc_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
color='purple', alpha=0.2, label='95% Confidence Interval')
axes[2, 5].set_xticks(months_scale)
axes[2, 5].set_xticklabels(month_names, rotation=45, ha="right")
axes[2, 5].set_title('d18Oc values')
axes[2, 5].set_xlabel('Month')
axes[2, 5].set_ylabel('d18Oc value')
# axes[2, 5].legend()
axes[2, 5].grid(True)
# Plot the prior distribution for precipitation
axes[3, 5].plot(months_scale, mu_prior_HadCM_old_2PIC_precip_monthly, label='Prior Precipitation Mean', color='teal', marker='o')
axes[3, 5].fill_between(months_scale,
mu_prior_HadCM_old_2PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_precip_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
mu_prior_HadCM_old_2PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_precip_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
color='teal', alpha=0.2, label='95% Confidence Interval')
axes[3, 5].set_xticks(months_scale)
axes[3, 5].set_xticklabels(month_names, rotation=45, ha="right")
axes[3, 5].set_title('Precipitation values')
axes[3, 5].set_xlabel('Month')
axes[3, 5].set_ylabel('Precipitation (mm/day)')
# axes[3, 5].legend()
axes[3, 5].grid(True)
# Now for priors for old HadCM model with 4x preindustrial CO2
# Plot the prior distribution for SST
axes[0, 6].plot(months_scale, mu_prior_HadCM_old_4PIC_SST_D47_monthly, label='Prior SST Mean', color='b', marker='o')
axes[0, 6].fill_between(months_scale,
mu_prior_HadCM_old_4PIC_SST_D47_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SST_D47_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
mu_prior_HadCM_old_4PIC_SST_D47_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SST_D47_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
axes[0, 6].set_xticks(months_scale)
axes[0, 6].set_xticklabels(month_names, rotation=45, ha="right")
axes[0, 6].set_title('HadCM (old)\n4x preindustrial pCO2\nSST D47 values')
axes[0, 6].set_xlabel('Month')
axes[0, 6].set_ylabel('D47 value')
# axes[0, 6].legend()
axes[0, 6].grid(True)
# Plot the prior distribution for SAT
axes[1, 6].plot(months_scale, mu_prior_HadCM_old_4PIC_SAT_D47_monthly, label='Prior SAT Mean', color='r', marker='o')
axes[1, 6].fill_between(months_scale,
mu_prior_HadCM_old_4PIC_SAT_D47_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SAT_D47_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
mu_prior_HadCM_old_4PIC_SAT_D47_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SAT_D47_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
axes[1, 6].set_xticks(months_scale)
axes[1, 6].set_xticklabels(month_names, rotation=45, ha="right")
axes[1, 6].set_title('SAT D47 values')
axes[1, 6].set_xlabel('Month')
axes[1, 6].set_ylabel('D47 value')
# axes[1, 6].legend()
axes[1, 6].grid(True)
# Plot the prior distribution for d18Oc
axes[2, 6].plot(months_scale, mu_prior_HadCM_old_4PIC_d18Oc_monthly, label='Prior d18Oc Mean', color='purple', marker='o')
axes[2, 6].fill_between(months_scale,
mu_prior_HadCM_old_4PIC_d18Oc_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_d18Oc_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
mu_prior_HadCM_old_4PIC_d18Oc_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_d18Oc_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
color='purple', alpha=0.2, label='95% Confidence Interval')
axes[2, 6].set_xticks(months_scale)
axes[2, 6].set_xticklabels(month_names, rotation=45, ha="right")
axes[2, 6].set_title('d18Oc values')
axes[2, 6].set_xlabel('Month')
axes[2, 6].set_ylabel('d18Oc value')
# axes[2, 6].legend()
axes[2, 6].grid(True)
# Plot the prior distribution for precipitation
axes[3, 6].plot(months_scale, mu_prior_HadCM_old_4PIC_precip_monthly, label='Prior Precipitation Mean', color='teal', marker='o')
axes[3, 6].fill_between(months_scale,
mu_prior_HadCM_old_4PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_precip_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
mu_prior_HadCM_old_4PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_precip_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
color='teal', alpha=0.2, label='95% Confidence Interval')
axes[3, 6].set_xticks(months_scale)
axes[3, 6].set_xticklabels(month_names, rotation=45, ha="right")
axes[3, 6].set_title('Precipitation values')
axes[3, 6].set_xlabel('Month')
axes[3, 6].set_ylabel('Precipitation (mm/day)')
# axes[3, 6].legend()
axes[3, 6].grid(True)
# Update the layout and show the plot
plt.tight_layout()
plt.show()
Calculate the monthly covariance matrix for D47 values of SST and SAT, d18Oc and precipitation¶
First for CESM model with 4x pre-industrial CO2¶
In [39]:
# Define column names for SAT, SST, d18Oc, and precipitation
SAT_D47_CESM_4PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_CESM_4PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_CESM_4PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_CESM_4PIC_columns_monthly = [f"{month}_precip" for month in months]
# Extract the relevant columns for SAT, SST D47, d18Oc, and precipitation
SAT_D47_CESM_4PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_CESM_4PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_CESM_4PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_CESM_4PIC_columns_monthly = [f"{month}_precip" for month in months]
# Combine the relevant columns into a single dataframe
combined_data_CESM_4PIC_monthly = Lutetian_CESM_4PIC_model[SAT_D47_CESM_4PIC_columns_monthly + SST_D47_CESM_4PIC_columns_monthly + d18Oc_CESM_4PIC_columns_monthly + precip_CESM_4PIC_columns_monthly]
# Calculate the covariance matrix for the combined data
cov_combined_CESM_4PIC_monthly = np.cov(combined_data_CESM_4PIC_monthly.dropna(), rowvar=False)
# Plot the heatmap of the raw combined covariance matrix
plt.figure(figsize=(12, 10))
sns.heatmap(
cov_combined_CESM_4PIC_monthly, # Use the raw covariance matrix
annot=False,
fmt=".2f",
cmap="coolwarm",
center=0,
xticklabels=SAT_D47_CESM_4PIC_columns_monthly + SST_D47_CESM_4PIC_columns_monthly + d18Oc_CESM_4PIC_columns_monthly + precip_CESM_4PIC_columns_monthly,
yticklabels=SAT_D47_CESM_4PIC_columns_monthly + SST_D47_CESM_4PIC_columns_monthly + d18Oc_CESM_4PIC_columns_monthly + precip_CESM_4PIC_columns_monthly
)
# Add titles to the axes per parameter
plt.axvline(x=len(SAT_D47_CESM_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly) + len(d18Oc_CESM_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_CESM_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly) + len(d18Oc_CESM_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
# Add parameter labels
plt.text(len(SAT_D47_CESM_4PIC_columns_monthly) / 2, -2, 'D47 value from SAT', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly) / 2, -2, 'D47 value from SST', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly) + len(d18Oc_CESM_4PIC_columns_monthly) / 2, -2, 'd18Oc', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly) + len(d18Oc_CESM_4PIC_columns_monthly) + len(precip_CESM_4PIC_columns_monthly) / 2, -2, 'Precipitation', ha='center', va='center', fontsize=10)
plt.text(-2, len(SAT_D47_CESM_4PIC_columns_monthly) / 2, 'D47 value from SAT', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly) / 2, 'D47 value from SST', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly) + len(d18Oc_CESM_4PIC_columns_monthly) / 2, 'd18Oc', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly) + len(d18Oc_CESM_4PIC_columns_monthly) + len(precip_CESM_4PIC_columns_monthly) / 2, 'Precipitation', ha='center', va='center', rotation=90, fontsize=10)
plt.title("Raw Combined Covariance Matrix (CESM 4x preindustrial pCO2)")
plt.show()
Then for CESM model with 2x pre-industrial CO2¶
In [40]:
# Define column names for SAT, SST, d18Oc, and precipitation
SAT_D47_CESM_2PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_CESM_2PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_CESM_2PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_CESM_2PIC_columns_monthly = [f"{month}_precip" for month in months]
# Extract the relevant columns for SAT, SST D47, d18Oc, and precipitation
SAT_D47_CESM_2PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_CESM_2PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_CESM_2PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_CESM_2PIC_columns_monthly = [f"{month}_precip" for month in months]
# Combine the relevant columns into a single dataframe
combined_data_CESM_2PIC_monthly = Lutetian_CESM_2PIC_model[SAT_D47_CESM_2PIC_columns_monthly + SST_D47_CESM_2PIC_columns_monthly + d18Oc_CESM_2PIC_columns_monthly + precip_CESM_2PIC_columns_monthly]
# Calculate the covariance matrix for the combined data
cov_combined_CESM_2PIC_monthly = np.cov(combined_data_CESM_2PIC_monthly.dropna(), rowvar=False)
# Plot the heatmap of the raw combined covariance matrix
plt.figure(figsize=(12, 10))
sns.heatmap(
cov_combined_CESM_2PIC_monthly, # Use the raw covariance matrix
annot=False,
fmt=".2f",
cmap="coolwarm",
center=0,
xticklabels=SAT_D47_CESM_2PIC_columns_monthly + SST_D47_CESM_2PIC_columns_monthly + d18Oc_CESM_2PIC_columns_monthly + precip_CESM_2PIC_columns_monthly,
yticklabels=SAT_D47_CESM_2PIC_columns_monthly + SST_D47_CESM_2PIC_columns_monthly + d18Oc_CESM_2PIC_columns_monthly + precip_CESM_2PIC_columns_monthly
)
# Add titles to the axes per parameter
plt.axvline(x=len(SAT_D47_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
# Add parameter labels
plt.text(len(SAT_D47_CESM_2PIC_columns_monthly) / 2, -2, 'D47 value from SAT', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) / 2, -2, 'D47 value from SST', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly) / 2, -2, 'd18Oc', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly) + len(precip_CESM_2PIC_columns_monthly) / 2, -2, 'Precipitation', ha='center', va='center', fontsize=10)
plt.text(-2, len(SAT_D47_CESM_2PIC_columns_monthly) / 2, 'D47 value from SAT', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) / 2, 'D47 value from SST', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly) / 2, 'd18Oc', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly) + len(precip_CESM_2PIC_columns_monthly) / 2, 'Precipitation', ha='center', va='center', rotation=90, fontsize=10)
plt.title("Raw Combined Covariance Matrix (CESM 2x preindustrial pCO2)")
plt.show()
Then for HadCM model with 1x pre-industrial CO2¶
In [41]:
# Define column names for SAT, SST, d18Oc, and precipitation
SAT_D47_HadCM_new_1PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_HadCM_new_1PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_HadCM_new_1PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_HadCM_new_1PIC_columns_monthly = [f"{month}_precip" for month in months]
# Extract the relevant columns for SAT, SST D47, d18Oc, and precipitation
SAT_D47_HadCM_new_1PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_HadCM_new_1PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_HadCM_new_1PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_HadCM_new_1PIC_columns_monthly = [f"{month}_precip" for month in months]
# Combine the relevant columns into a single dataframe
combined_data_HadCM_new_1PIC_monthly = Lutetian_HadCM_new_1PIC_model[SAT_D47_HadCM_new_1PIC_columns_monthly + SST_D47_HadCM_new_1PIC_columns_monthly + d18Oc_HadCM_new_1PIC_columns_monthly + precip_HadCM_new_1PIC_columns_monthly]
# Calculate the covariance matrix for the combined data
cov_combined_HadCM_new_1PIC_monthly = np.cov(combined_data_HadCM_new_1PIC_monthly.dropna(), rowvar=False)
# Plot the heatmap of the raw combined covariance matrix
plt.figure(figsize=(12, 10))
sns.heatmap(
cov_combined_HadCM_new_1PIC_monthly, # Use the raw covariance matrix
annot=False,
fmt=".2f",
cmap="coolwarm",
center=0,
xticklabels=SAT_D47_HadCM_new_1PIC_columns_monthly + SST_D47_HadCM_new_1PIC_columns_monthly + d18Oc_HadCM_new_1PIC_columns_monthly + precip_HadCM_new_1PIC_columns_monthly,
yticklabels=SAT_D47_HadCM_new_1PIC_columns_monthly + SST_D47_HadCM_new_1PIC_columns_monthly + d18Oc_HadCM_new_1PIC_columns_monthly + precip_HadCM_new_1PIC_columns_monthly
)
# Add titles to the axes per parameter
plt.axvline(x=len(SAT_D47_HadCM_new_1PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly) + len(d18Oc_HadCM_new_1PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_1PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly) + len(d18Oc_HadCM_new_1PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
# Add parameter labels
plt.text(len(SAT_D47_HadCM_new_1PIC_columns_monthly) / 2, -2, 'D47 value from SAT', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly) / 2, -2, 'D47 value from SST', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly) + len(d18Oc_HadCM_new_1PIC_columns_monthly) / 2, -2, 'd18Oc', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly) + len(d18Oc_HadCM_new_1PIC_columns_monthly) + len(precip_HadCM_new_1PIC_columns_monthly) / 2, -2, 'Precipitation', ha='center', va='center', fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_new_1PIC_columns_monthly) / 2, 'D47 value from SAT', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly) / 2, 'D47 value from SST', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly) + len(d18Oc_HadCM_new_1PIC_columns_monthly) / 2, 'd18Oc', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly) + len(d18Oc_HadCM_new_1PIC_columns_monthly) + len(precip_HadCM_new_1PIC_columns_monthly) / 2, 'Precipitation', ha='center', va='center', rotation=90, fontsize=10)
plt.title("Raw Combined Covariance Matrix (CESM 2x preindustrial pCO2)")
plt.show()
Then for HadCM model with 2x pre-industrial CO2¶
In [42]:
# Define column names for SAT, SST, d18Oc, and precipitation
SAT_D47_HadCM_new_2PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_HadCM_new_2PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_HadCM_new_2PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_HadCM_new_2PIC_columns_monthly = [f"{month}_precip" for month in months]
# Extract the relevant columns for SAT, SST D47, d18Oc, and precipitation
SAT_D47_HadCM_new_2PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_HadCM_new_2PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_HadCM_new_2PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_HadCM_new_2PIC_columns_monthly = [f"{month}_precip" for month in months]
# Combine the relevant columns into a single dataframe
combined_data_HadCM_new_2PIC_monthly = Lutetian_HadCM_new_2PIC_model[SAT_D47_HadCM_new_2PIC_columns_monthly + SST_D47_HadCM_new_2PIC_columns_monthly + d18Oc_HadCM_new_2PIC_columns_monthly + precip_HadCM_new_2PIC_columns_monthly]
# Calculate the covariance matrix for the combined data
cov_combined_HadCM_new_2PIC_monthly = np.cov(combined_data_HadCM_new_2PIC_monthly.dropna(), rowvar=False)
# Plot the heatmap of the raw combined covariance matrix
plt.figure(figsize=(12, 10))
sns.heatmap(
cov_combined_HadCM_new_2PIC_monthly, # Use the raw covariance matrix
annot=False,
fmt=".2f",
cmap="coolwarm",
center=0,
xticklabels=SAT_D47_HadCM_new_2PIC_columns_monthly + SST_D47_HadCM_new_2PIC_columns_monthly + d18Oc_HadCM_new_2PIC_columns_monthly + precip_HadCM_new_2PIC_columns_monthly,
yticklabels=SAT_D47_HadCM_new_2PIC_columns_monthly + SST_D47_HadCM_new_2PIC_columns_monthly + d18Oc_HadCM_new_2PIC_columns_monthly + precip_HadCM_new_2PIC_columns_monthly
)
# Add titles to the axes per parameter
plt.axvline(x=len(SAT_D47_HadCM_new_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly) + len(d18Oc_HadCM_new_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly) + len(d18Oc_HadCM_new_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
# Add parameter labels
plt.text(len(SAT_D47_HadCM_new_2PIC_columns_monthly) / 2, -2, 'D47 value from SAT', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly) / 2, -2, 'D47 value from SST', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly) + len(d18Oc_HadCM_new_2PIC_columns_monthly) / 2, -2, 'd18Oc', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly) + len(d18Oc_HadCM_new_2PIC_columns_monthly) + len(precip_HadCM_new_2PIC_columns_monthly) / 2, -2, 'Precipitation', ha='center', va='center', fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_new_2PIC_columns_monthly) / 2, 'D47 value from SAT', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly) / 2, 'D47 value from SST', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly) + len(d18Oc_HadCM_new_2PIC_columns_monthly) / 2, 'd18Oc', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly) + len(d18Oc_HadCM_new_2PIC_columns_monthly) + len(precip_HadCM_new_2PIC_columns_monthly) / 2, 'Precipitation', ha='center', va='center', rotation=90, fontsize=10)
plt.title("Raw Combined Covariance Matrix (CESM 2x preindustrial pCO2)")
plt.show()
Then for HadCM model with 1056 ppm CO2¶
In [43]:
# Define column names for SAT, SST, d18Oc, and precipitation
SAT_D47_HadCM_new_1056ppm_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_HadCM_new_1056ppm_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_HadCM_new_1056ppm_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_HadCM_new_1056ppm_columns_monthly = [f"{month}_precip" for month in months]
# Extract the relevant columns for SAT, SST D47, d18Oc, and precipitation
SAT_D47_HadCM_new_1056ppm_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_HadCM_new_1056ppm_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_HadCM_new_1056ppm_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_HadCM_new_1056ppm_columns_monthly = [f"{month}_precip" for month in months]
# Combine the relevant columns into a single dataframe
combined_data_HadCM_new_1056ppm_monthly = Lutetian_HadCM_new_1056ppm_model[SAT_D47_HadCM_new_1056ppm_columns_monthly + SST_D47_HadCM_new_1056ppm_columns_monthly + d18Oc_HadCM_new_1056ppm_columns_monthly + precip_HadCM_new_1056ppm_columns_monthly]
# Calculate the covariance matrix for the combined data
cov_combined_HadCM_new_1056ppm_monthly = np.cov(combined_data_HadCM_new_1056ppm_monthly.dropna(), rowvar=False)
# Plot the heatmap of the raw combined covariance matrix
plt.figure(figsize=(12, 10))
sns.heatmap(
cov_combined_HadCM_new_1056ppm_monthly, # Use the raw covariance matrix
annot=False,
fmt=".2f",
cmap="coolwarm",
center=0,
xticklabels=SAT_D47_HadCM_new_1056ppm_columns_monthly + SST_D47_HadCM_new_1056ppm_columns_monthly + d18Oc_HadCM_new_1056ppm_columns_monthly + precip_HadCM_new_1056ppm_columns_monthly,
yticklabels=SAT_D47_HadCM_new_1056ppm_columns_monthly + SST_D47_HadCM_new_1056ppm_columns_monthly + d18Oc_HadCM_new_1056ppm_columns_monthly + precip_HadCM_new_1056ppm_columns_monthly
)
# Add titles to the axes per parameter
plt.axvline(x=len(SAT_D47_HadCM_new_1056ppm_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly) + len(d18Oc_HadCM_new_1056ppm_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_1056ppm_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly) + len(d18Oc_HadCM_new_1056ppm_columns_monthly), color='black', linestyle='--', linewidth=1)
# Add parameter labels
plt.text(len(SAT_D47_HadCM_new_1056ppm_columns_monthly) / 2, -2, 'D47 value from SAT', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly) / 2, -2, 'D47 value from SST', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly) + len(d18Oc_HadCM_new_1056ppm_columns_monthly) / 2, -2, 'd18Oc', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly) + len(d18Oc_HadCM_new_1056ppm_columns_monthly) + len(precip_HadCM_new_1056ppm_columns_monthly) / 2, -2, 'Precipitation', ha='center', va='center', fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_new_1056ppm_columns_monthly) / 2, 'D47 value from SAT', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly) / 2, 'D47 value from SST', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly) + len(d18Oc_HadCM_new_1056ppm_columns_monthly) / 2, 'd18Oc', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly) + len(d18Oc_HadCM_new_1056ppm_columns_monthly) + len(precip_HadCM_new_1056ppm_columns_monthly) / 2, 'Precipitation', ha='center', va='center', rotation=90, fontsize=10)
plt.title("Raw Combined Covariance Matrix (CESM 2x preindustrial pCO2)")
plt.show()
Then for old HadCM model with 2x pre-industrial CO2¶
In [44]:
# Define column names for SAT, SST, d18Oc, and precipitation
SAT_D47_HadCM_old_2PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_HadCM_old_2PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_HadCM_old_2PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_HadCM_old_2PIC_columns_monthly = [f"{month}_precip" for month in months]
# Extract the relevant columns for SAT, SST D47, d18Oc, and precipitation
SAT_D47_HadCM_old_2PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_HadCM_old_2PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_HadCM_old_2PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_HadCM_old_2PIC_columns_monthly = [f"{month}_precip" for month in months]
# Combine the relevant columns into a single dataframe
combined_data_HadCM_old_2PIC_monthly = Lutetian_HadCM_old_2PIC_model[SAT_D47_HadCM_old_2PIC_columns_monthly + SST_D47_HadCM_old_2PIC_columns_monthly + d18Oc_HadCM_old_2PIC_columns_monthly + precip_HadCM_old_2PIC_columns_monthly]
# Calculate the covariance matrix for the combined data
cov_combined_HadCM_old_2PIC_monthly = np.cov(combined_data_HadCM_old_2PIC_monthly.dropna(), rowvar=False)
# Plot the heatmap of the raw combined covariance matrix
plt.figure(figsize=(12, 10))
sns.heatmap(
cov_combined_HadCM_old_2PIC_monthly, # Use the raw covariance matrix
annot=False,
fmt=".2f",
cmap="coolwarm",
center=0,
xticklabels=SAT_D47_HadCM_old_2PIC_columns_monthly + SST_D47_HadCM_old_2PIC_columns_monthly + d18Oc_HadCM_old_2PIC_columns_monthly + precip_HadCM_old_2PIC_columns_monthly,
yticklabels=SAT_D47_HadCM_old_2PIC_columns_monthly + SST_D47_HadCM_old_2PIC_columns_monthly + d18Oc_HadCM_old_2PIC_columns_monthly + precip_HadCM_old_2PIC_columns_monthly
)
# Add titles to the axes per parameter
plt.axvline(x=len(SAT_D47_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
# Add parameter labels
plt.text(len(SAT_D47_HadCM_old_2PIC_columns_monthly) / 2, -2, 'D47 value from SAT', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) / 2, -2, 'D47 value from SST', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly) / 2, -2, 'd18Oc', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly) + len(precip_HadCM_old_2PIC_columns_monthly) / 2, -2, 'Precipitation', ha='center', va='center', fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_old_2PIC_columns_monthly) / 2, 'D47 value from SAT', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) / 2, 'D47 value from SST', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly) / 2, 'd18Oc', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly) + len(precip_HadCM_old_2PIC_columns_monthly) / 2, 'Precipitation', ha='center', va='center', rotation=90, fontsize=10)
plt.title("Raw Combined Covariance Matrix (CESM 2x preindustrial pCO2)")
plt.show()
Then for old HadCM model with 4x pre-industrial CO2¶
In [45]:
# Define column names for SAT, SST, d18Oc, and precipitation
SAT_D47_HadCM_old_4PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_HadCM_old_4PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_HadCM_old_4PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_HadCM_old_4PIC_columns_monthly = [f"{month}_precip" for month in months]
# Extract the relevant columns for SAT, SST D47, d18Oc, and precipitation
SAT_D47_HadCM_old_4PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_HadCM_old_4PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_HadCM_old_4PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_HadCM_old_4PIC_columns_monthly = [f"{month}_precip" for month in months]
# Combine the relevant columns into a single dataframe
combined_data_HadCM_old_4PIC_monthly = Lutetian_HadCM_old_4PIC_model[SAT_D47_HadCM_old_4PIC_columns_monthly + SST_D47_HadCM_old_4PIC_columns_monthly + d18Oc_HadCM_old_4PIC_columns_monthly + precip_HadCM_old_4PIC_columns_monthly]
# Calculate the covariance matrix for the combined data
cov_combined_HadCM_old_4PIC_monthly = np.cov(combined_data_HadCM_old_4PIC_monthly.dropna(), rowvar=False)
# Plot the heatmap of the raw combined covariance matrix
plt.figure(figsize=(12, 10))
sns.heatmap(
cov_combined_HadCM_old_4PIC_monthly, # Use the raw covariance matrix
annot=False,
fmt=".2f",
cmap="coolwarm",
center=0,
xticklabels=SAT_D47_HadCM_old_4PIC_columns_monthly + SST_D47_HadCM_old_4PIC_columns_monthly + d18Oc_HadCM_old_4PIC_columns_monthly + precip_HadCM_old_4PIC_columns_monthly,
yticklabels=SAT_D47_HadCM_old_4PIC_columns_monthly + SST_D47_HadCM_old_4PIC_columns_monthly + d18Oc_HadCM_old_4PIC_columns_monthly + precip_HadCM_old_4PIC_columns_monthly
)
# Add titles to the axes per parameter
plt.axvline(x=len(SAT_D47_HadCM_old_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly) + len(d18Oc_HadCM_old_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_old_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly) + len(d18Oc_HadCM_old_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
# Add parameter labels
plt.text(len(SAT_D47_HadCM_old_4PIC_columns_monthly) / 2, -2, 'D47 value from SAT', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly) / 2, -2, 'D47 value from SST', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly) + len(d18Oc_HadCM_old_4PIC_columns_monthly) / 2, -2, 'd18Oc', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly) + len(d18Oc_HadCM_old_4PIC_columns_monthly) + len(precip_HadCM_old_4PIC_columns_monthly) / 2, -2, 'Precipitation', ha='center', va='center', fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_old_4PIC_columns_monthly) / 2, 'D47 value from SAT', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly) / 2, 'D47 value from SST', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly) + len(d18Oc_HadCM_old_4PIC_columns_monthly) / 2, 'd18Oc', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-2, len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly) + len(d18Oc_HadCM_old_4PIC_columns_monthly) + len(precip_HadCM_old_4PIC_columns_monthly) / 2, 'Precipitation', ha='center', va='center', rotation=90, fontsize=10)
plt.title("Raw Combined Covariance Matrix (CESM 2x preindustrial pCO2)")
plt.show()
Plot normalized monthly covariance matrix between D47 values of SST and SAT, d18Oc and precipitation¶
Create function for normalizing matrices¶
In [46]:
# Normalize each submatrix independently for better visualization
def normalize_matrix(matrix):
min_val = np.min(matrix)
max_val = np.max(matrix)
return (matrix - min_val) / (max_val - min_val)
First for CESM with 4x preindustrial pCO2¶
In [47]:
# Extract the relevant columns for SAT, SST D47, d18Oc, and precipitation
SAT_D47_CESM_4PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_CESM_4PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_CESM_4PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_CESM_4PIC_columns_monthly = [f"{month}_precip" for month in months]
# Combine the relevant columns into a single dataframe
combined_data_CESM_4PIC_monthly = Lutetian_CESM_4PIC_model[SAT_D47_CESM_4PIC_columns_monthly + SST_D47_CESM_4PIC_columns_monthly + d18Oc_CESM_4PIC_columns_monthly + precip_CESM_4PIC_columns_monthly]
# Calculate the covariance matrix for the combined data
cov_combined_CESM_4PIC_monthly = np.cov(combined_data_CESM_4PIC_monthly.dropna(), rowvar=False)
# Extract the covariance matrices for SAT D47, SST D47, d18Oc, and precipitation
cov_CESM_4PIC_SAT_D47_monthly = cov_combined_CESM_4PIC_monthly[:len(months), :len(months)]
cov_CESM_4PIC_SST_D47_monthly = cov_combined_CESM_4PIC_monthly[len(months):2*len(months), len(months):2*len(months)]
cov_CESM_4PIC_d18Oc_monthly = cov_combined_CESM_4PIC_monthly[2*len(months):3*len(months), 2*len(months):3*len(months)]
cov_CESM_4PIC_precip_monthly = cov_combined_CESM_4PIC_monthly[3*len(months):, 3*len(months):]
# Extract the cross-covariance matrices
cross_cov_CESM_4PIC_SAT_SST_D47_monthly = cov_combined_CESM_4PIC_monthly[:len(months), len(months):2*len(months)]
cross_cov_CESM_4PIC_SAT_d18Oc_monthly = cov_combined_CESM_4PIC_monthly[:len(months), 2*len(months):3*len(months)]
cross_cov_CESM_4PIC_SAT_precip_monthly = cov_combined_CESM_4PIC_monthly[:len(months), 3*len(months):]
cross_cov_CESM_4PIC_SST_d18Oc_monthly = cov_combined_CESM_4PIC_monthly[len(months):2*len(months), 2*len(months):3*len(months)]
cross_cov_CESM_4PIC_SST_precip_monthly = cov_combined_CESM_4PIC_monthly[len(months):2*len(months), 3*len(months):]
cross_cov_CESM_4PIC_d18Oc_precip_monthly = cov_combined_CESM_4PIC_monthly[2*len(months):3*len(months), 3*len(months):]
# Normalize each submatrix
normalized_cov_CESM_4PIC_SAT_D47_monthly = normalize_matrix(cov_CESM_4PIC_SAT_D47_monthly)
normalized_cov_CESM_4PIC_SST_D47_monthly = normalize_matrix(cov_CESM_4PIC_SST_D47_monthly)
normalized_cov_CESM_4PIC_d18Oc_monthly = normalize_matrix(cov_CESM_4PIC_d18Oc_monthly)
normalized_cov_CESM_4PIC_precip_monthly = normalize_matrix(cov_CESM_4PIC_precip_monthly)
# Normalize each cross-covariance matrix
normalized_cross_cov_CESM_4PIC_SAT_SST_D47_monthly = normalize_matrix(cross_cov_CESM_4PIC_SAT_SST_D47_monthly)
normalized_cross_cov_CESM_4PIC_SAT_d18Oc_monthly = normalize_matrix(cross_cov_CESM_4PIC_SAT_d18Oc_monthly)
normalized_cross_cov_CESM_4PIC_SAT_precip_monthly = normalize_matrix(cross_cov_CESM_4PIC_SAT_precip_monthly)
normalized_cross_cov_CESM_4PIC_SST_d18Oc_monthly = normalize_matrix(cross_cov_CESM_4PIC_SST_d18Oc_monthly)
normalized_cross_cov_CESM_4PIC_SST_precip_monthly = normalize_matrix(cross_cov_CESM_4PIC_SST_precip_monthly)
normalized_cross_cov_CESM_4PIC_d18Oc_precip_monthly = normalize_matrix(cross_cov_CESM_4PIC_d18Oc_precip_monthly)
# Combine the normalized submatrices into a single normalized covariance matrix
normalized_cov_combined_CESM_4PIC_monthly = np.block([
[normalized_cov_CESM_4PIC_SAT_D47_monthly, normalized_cross_cov_CESM_4PIC_SAT_SST_D47_monthly, normalized_cross_cov_CESM_4PIC_SAT_d18Oc_monthly, normalized_cross_cov_CESM_4PIC_SAT_precip_monthly],
[normalized_cross_cov_CESM_4PIC_SAT_SST_D47_monthly.T, normalized_cov_CESM_4PIC_SST_D47_monthly, normalized_cross_cov_CESM_4PIC_SST_d18Oc_monthly, normalized_cross_cov_CESM_4PIC_SST_precip_monthly],
[normalized_cross_cov_CESM_4PIC_SAT_d18Oc_monthly.T, normalized_cross_cov_CESM_4PIC_SST_d18Oc_monthly.T, normalized_cov_CESM_4PIC_d18Oc_monthly, normalized_cross_cov_CESM_4PIC_d18Oc_precip_monthly],
[normalized_cross_cov_CESM_4PIC_SAT_precip_monthly.T, normalized_cross_cov_CESM_4PIC_SST_precip_monthly.T, normalized_cross_cov_CESM_4PIC_d18Oc_precip_monthly.T, normalized_cov_CESM_4PIC_precip_monthly]
])
# Plot the heatmap of the normalized combined covariance matrix
plt.figure(figsize=(12, 10))
sns.heatmap(
normalized_cov_combined_CESM_4PIC_monthly,
annot=False,
fmt=".2f",
cmap="coolwarm",
center=0,
xticklabels=SAT_D47_CESM_4PIC_columns_monthly + SST_D47_CESM_4PIC_columns_monthly + d18Oc_CESM_4PIC_columns_monthly + precip_CESM_4PIC_columns_monthly,
yticklabels=SAT_D47_CESM_4PIC_columns_monthly + SST_D47_CESM_4PIC_columns_monthly + d18Oc_CESM_4PIC_columns_monthly + precip_CESM_4PIC_columns_monthly
)
# Add titles to the axes per parameter
plt.axvline(x=len(SAT_D47_CESM_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly) + len(d18Oc_CESM_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_CESM_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly) + len(d18Oc_CESM_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
# Add parameter labels
plt.text(len(SAT_D47_CESM_4PIC_columns_monthly) / 2, -2, 'D47 value from SAT', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly) / 2, -2, 'D47 value from SST', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly) + len(d18Oc_CESM_4PIC_columns_monthly) / 2, -2, 'd18Oc', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly) + len(d18Oc_CESM_4PIC_columns_monthly) + len(precip_CESM_4PIC_columns_monthly) / 2, -2, 'Precipitation', ha='center', va='center', fontsize=10)
plt.text(-7, len(SAT_D47_CESM_4PIC_columns_monthly) / 2, 'D47 value from SAT', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly) / 2, 'D47 value from SST', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly) + len(d18Oc_CESM_4PIC_columns_monthly) / 2, 'd18Oc', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_CESM_4PIC_columns_monthly) + len(SST_D47_CESM_4PIC_columns_monthly) + len(d18Oc_CESM_4PIC_columns_monthly) + len(precip_CESM_4PIC_columns_monthly) / 2, 'Precipitation', ha='center', va='center', rotation=90, fontsize=10)
plt.title("Normalized Combined Covariance Matrix (CESM 4x preindustrial pCO2)")
plt.show()
CESM with 2x preindustrial pCO2¶
In [48]:
# Extract the relevant columns for SAT, SST D47, d18Oc, and precipitation
SAT_D47_CESM_2PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_CESM_2PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_CESM_2PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_CESM_2PIC_columns_monthly = [f"{month}_precip" for month in months]
# Combine the relevant columns into a single dataframe
combined_data_CESM_2PIC_monthly = Lutetian_CESM_2PIC_model[SAT_D47_CESM_2PIC_columns_monthly + SST_D47_CESM_2PIC_columns_monthly + d18Oc_CESM_2PIC_columns_monthly + precip_CESM_2PIC_columns_monthly]
# Calculate the covariance matrix for the combined data
cov_combined_CESM_2PIC_monthly = np.cov(combined_data_CESM_2PIC_monthly.dropna(), rowvar=False)
# Extract the covariance matrices for SAT D47, SST D47, d18Oc, and precipitation
cov_CESM_2PIC_SAT_D47_monthly = cov_combined_CESM_2PIC_monthly[:len(months), :len(months)]
cov_CESM_2PIC_SST_D47_monthly = cov_combined_CESM_2PIC_monthly[len(months):2*len(months), len(months):2*len(months)]
cov_CESM_2PIC_d18Oc_monthly = cov_combined_CESM_2PIC_monthly[2*len(months):3*len(months), 2*len(months):3*len(months)]
cov_CESM_2PIC_precip_monthly = cov_combined_CESM_2PIC_monthly[3*len(months):, 3*len(months):]
# Extract the cross-covariance matrices
cross_cov_CESM_2PIC_SAT_SST_D47_monthly = cov_combined_CESM_2PIC_monthly[:len(months), len(months):2*len(months)]
cross_cov_CESM_2PIC_SAT_d18Oc_monthly = cov_combined_CESM_2PIC_monthly[:len(months), 2*len(months):3*len(months)]
cross_cov_CESM_2PIC_SAT_precip_monthly = cov_combined_CESM_2PIC_monthly[:len(months), 3*len(months):]
cross_cov_CESM_2PIC_SST_d18Oc_monthly = cov_combined_CESM_2PIC_monthly[len(months):2*len(months), 2*len(months):3*len(months)]
cross_cov_CESM_2PIC_SST_precip_monthly = cov_combined_CESM_2PIC_monthly[len(months):2*len(months), 3*len(months):]
cross_cov_CESM_2PIC_d18Oc_precip_monthly = cov_combined_CESM_2PIC_monthly[2*len(months):3*len(months), 3*len(months):]
# Normalize each submatrix
normalized_cov_CESM_2PIC_SAT_D47_monthly = normalize_matrix(cov_CESM_2PIC_SAT_D47_monthly)
normalized_cov_CESM_2PIC_SST_D47_monthly = normalize_matrix(cov_CESM_2PIC_SST_D47_monthly)
normalized_cov_CESM_2PIC_d18Oc_monthly = normalize_matrix(cov_CESM_2PIC_d18Oc_monthly)
normalized_cov_CESM_2PIC_precip_monthly = normalize_matrix(cov_CESM_2PIC_precip_monthly)
# Normalize each cross-covariance matrix
normalized_cross_cov_CESM_2PIC_SAT_SST_D47_monthly = normalize_matrix(cross_cov_CESM_2PIC_SAT_SST_D47_monthly)
normalized_cross_cov_CESM_2PIC_SAT_d18Oc_monthly = normalize_matrix(cross_cov_CESM_2PIC_SAT_d18Oc_monthly)
normalized_cross_cov_CESM_2PIC_SAT_precip_monthly = normalize_matrix(cross_cov_CESM_2PIC_SAT_precip_monthly)
normalized_cross_cov_CESM_2PIC_SST_d18Oc_monthly = normalize_matrix(cross_cov_CESM_2PIC_SST_d18Oc_monthly)
normalized_cross_cov_CESM_2PIC_SST_precip_monthly = normalize_matrix(cross_cov_CESM_2PIC_SST_precip_monthly)
normalized_cross_cov_CESM_2PIC_d18Oc_precip_monthly = normalize_matrix(cross_cov_CESM_2PIC_d18Oc_precip_monthly)
# Combine the normalized submatrices into a single normalized covariance matrix
normalized_cov_combined_CESM_2PIC_monthly = np.block([
[normalized_cov_CESM_2PIC_SAT_D47_monthly, normalized_cross_cov_CESM_2PIC_SAT_SST_D47_monthly, normalized_cross_cov_CESM_2PIC_SAT_d18Oc_monthly, normalized_cross_cov_CESM_2PIC_SAT_precip_monthly],
[normalized_cross_cov_CESM_2PIC_SAT_SST_D47_monthly.T, normalized_cov_CESM_2PIC_SST_D47_monthly, normalized_cross_cov_CESM_2PIC_SST_d18Oc_monthly, normalized_cross_cov_CESM_2PIC_SST_precip_monthly],
[normalized_cross_cov_CESM_2PIC_SAT_d18Oc_monthly.T, normalized_cross_cov_CESM_2PIC_SST_d18Oc_monthly.T, normalized_cov_CESM_2PIC_d18Oc_monthly, normalized_cross_cov_CESM_2PIC_d18Oc_precip_monthly],
[normalized_cross_cov_CESM_2PIC_SAT_precip_monthly.T, normalized_cross_cov_CESM_2PIC_SST_precip_monthly.T, normalized_cross_cov_CESM_2PIC_d18Oc_precip_monthly.T, normalized_cov_CESM_2PIC_precip_monthly]
])
# Plot the heatmap of the normalized combined covariance matrix
plt.figure(figsize=(12, 10))
sns.heatmap(
normalized_cov_combined_CESM_2PIC_monthly,
annot=False,
fmt=".2f",
cmap="coolwarm",
center=0,
xticklabels=SAT_D47_CESM_2PIC_columns_monthly + SST_D47_CESM_2PIC_columns_monthly + d18Oc_CESM_2PIC_columns_monthly + precip_CESM_2PIC_columns_monthly,
yticklabels=SAT_D47_CESM_2PIC_columns_monthly + SST_D47_CESM_2PIC_columns_monthly + d18Oc_CESM_2PIC_columns_monthly + precip_CESM_2PIC_columns_monthly
)
# Add titles to the axes per parameter
plt.axvline(x=len(SAT_D47_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
# Add parameter labels
plt.text(len(SAT_D47_CESM_2PIC_columns_monthly) / 2, -2, 'D47 value from SAT', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) / 2, -2, 'D47 value from SST', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly) / 2, -2, 'd18Oc', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly) + len(precip_CESM_2PIC_columns_monthly) / 2, -2, 'Precipitation', ha='center', va='center', fontsize=10)
plt.text(-7, len(SAT_D47_CESM_2PIC_columns_monthly) / 2, 'D47 value from SAT', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) / 2, 'D47 value from SST', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly) / 2, 'd18Oc', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly) + len(precip_CESM_2PIC_columns_monthly) / 2, 'Precipitation', ha='center', va='center', rotation=90, fontsize=10)
plt.title("Normalized Combined Covariance Matrix (CESM 2x preindustrial pCO2)")
plt.show()
HadCM with 1x preindustrial pCO2¶
In [49]:
# Extract the relevant columns for SAT, SST D47, d18Oc, and precipitation
SAT_D47_HadCM_new_1PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_HadCM_new_1PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_HadCM_new_1PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_HadCM_new_1PIC_columns_monthly = [f"{month}_precip" for month in months]
# Combine the relevant columns into a single dataframe
combined_data_HadCM_new_1PIC_monthly = Lutetian_HadCM_new_1PIC_model[SAT_D47_HadCM_new_1PIC_columns_monthly + SST_D47_HadCM_new_1PIC_columns_monthly + d18Oc_HadCM_new_1PIC_columns_monthly + precip_HadCM_new_1PIC_columns_monthly]
# Calculate the covariance matrix for the combined data
cov_combined_HadCM_new_1PIC_monthly = np.cov(combined_data_HadCM_new_1PIC_monthly.dropna(), rowvar=False)
# Extract the covariance matrices for SAT D47, SST D47, d18Oc, and precipitation
cov_HadCM_new_1PIC_SAT_D47_monthly = cov_combined_HadCM_new_1PIC_monthly[:len(months), :len(months)]
cov_HadCM_new_1PIC_SST_D47_monthly = cov_combined_HadCM_new_1PIC_monthly[len(months):2*len(months), len(months):2*len(months)]
cov_HadCM_new_1PIC_d18Oc_monthly = cov_combined_HadCM_new_1PIC_monthly[2*len(months):3*len(months), 2*len(months):3*len(months)]
cov_HadCM_new_1PIC_precip_monthly = cov_combined_HadCM_new_1PIC_monthly[3*len(months):, 3*len(months):]
# Extract the cross-covariance matrices
cross_cov_HadCM_new_1PIC_SAT_SST_D47_monthly = cov_combined_HadCM_new_1PIC_monthly[:len(months), len(months):2*len(months)]
cross_cov_HadCM_new_1PIC_SAT_d18Oc_monthly = cov_combined_HadCM_new_1PIC_monthly[:len(months), 2*len(months):3*len(months)]
cross_cov_HadCM_new_1PIC_SAT_precip_monthly = cov_combined_HadCM_new_1PIC_monthly[:len(months), 3*len(months):]
cross_cov_HadCM_new_1PIC_SST_d18Oc_monthly = cov_combined_HadCM_new_1PIC_monthly[len(months):2*len(months), 2*len(months):3*len(months)]
cross_cov_HadCM_new_1PIC_SST_precip_monthly = cov_combined_HadCM_new_1PIC_monthly[len(months):2*len(months), 3*len(months):]
cross_cov_HadCM_new_1PIC_d18Oc_precip_monthly = cov_combined_HadCM_new_1PIC_monthly[2*len(months):3*len(months), 3*len(months):]
# Normalize each submatrix
normalized_cov_HadCM_new_1PIC_SAT_D47_monthly = normalize_matrix(cov_HadCM_new_1PIC_SAT_D47_monthly)
normalized_cov_HadCM_new_1PIC_SST_D47_monthly = normalize_matrix(cov_HadCM_new_1PIC_SST_D47_monthly)
normalized_cov_HadCM_new_1PIC_d18Oc_monthly = normalize_matrix(cov_HadCM_new_1PIC_d18Oc_monthly)
normalized_cov_HadCM_new_1PIC_precip_monthly = normalize_matrix(cov_HadCM_new_1PIC_precip_monthly)
# Normalize each cross-covariance matrix
normalized_cross_cov_HadCM_new_1PIC_SAT_SST_D47_monthly = normalize_matrix(cross_cov_HadCM_new_1PIC_SAT_SST_D47_monthly)
normalized_cross_cov_HadCM_new_1PIC_SAT_d18Oc_monthly = normalize_matrix(cross_cov_HadCM_new_1PIC_SAT_d18Oc_monthly)
normalized_cross_cov_HadCM_new_1PIC_SAT_precip_monthly = normalize_matrix(cross_cov_HadCM_new_1PIC_SAT_precip_monthly)
normalized_cross_cov_HadCM_new_1PIC_SST_d18Oc_monthly = normalize_matrix(cross_cov_HadCM_new_1PIC_SST_d18Oc_monthly)
normalized_cross_cov_HadCM_new_1PIC_SST_precip_monthly = normalize_matrix(cross_cov_HadCM_new_1PIC_SST_precip_monthly)
normalized_cross_cov_HadCM_new_1PIC_d18Oc_precip_monthly = normalize_matrix(cross_cov_HadCM_new_1PIC_d18Oc_precip_monthly)
# Combine the normalized submatrices into a single normalized covariance matrix
normalized_cov_combined_HadCM_new_1PIC_monthly = np.block([
[normalized_cov_HadCM_new_1PIC_SAT_D47_monthly, normalized_cross_cov_HadCM_new_1PIC_SAT_SST_D47_monthly, normalized_cross_cov_HadCM_new_1PIC_SAT_d18Oc_monthly, normalized_cross_cov_HadCM_new_1PIC_SAT_precip_monthly],
[normalized_cross_cov_HadCM_new_1PIC_SAT_SST_D47_monthly.T, normalized_cov_HadCM_new_1PIC_SST_D47_monthly, normalized_cross_cov_HadCM_new_1PIC_SST_d18Oc_monthly, normalized_cross_cov_HadCM_new_1PIC_SST_precip_monthly],
[normalized_cross_cov_HadCM_new_1PIC_SAT_d18Oc_monthly.T, normalized_cross_cov_HadCM_new_1PIC_SST_d18Oc_monthly.T, normalized_cov_HadCM_new_1PIC_d18Oc_monthly, normalized_cross_cov_HadCM_new_1PIC_d18Oc_precip_monthly],
[normalized_cross_cov_HadCM_new_1PIC_SAT_precip_monthly.T, normalized_cross_cov_HadCM_new_1PIC_SST_precip_monthly.T, normalized_cross_cov_HadCM_new_1PIC_d18Oc_precip_monthly.T, normalized_cov_HadCM_new_1PIC_precip_monthly]
])
# Plot the heatmap of the normalized combined covariance matrix
plt.figure(figsize=(12, 10))
sns.heatmap(
normalized_cov_combined_HadCM_new_1PIC_monthly,
annot=False,
fmt=".2f",
cmap="coolwarm",
center=0,
xticklabels=SAT_D47_HadCM_new_1PIC_columns_monthly + SST_D47_HadCM_new_1PIC_columns_monthly + d18Oc_HadCM_new_1PIC_columns_monthly + precip_HadCM_new_1PIC_columns_monthly,
yticklabels=SAT_D47_HadCM_new_1PIC_columns_monthly + SST_D47_HadCM_new_1PIC_columns_monthly + d18Oc_HadCM_new_1PIC_columns_monthly + precip_HadCM_new_1PIC_columns_monthly
)
# Add titles to the axes per parameter
plt.axvline(x=len(SAT_D47_HadCM_new_1PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly) + len(d18Oc_HadCM_new_1PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_1PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly) + len(d18Oc_HadCM_new_1PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
# Add parameter labels
plt.text(len(SAT_D47_HadCM_new_1PIC_columns_monthly) / 2, -2, 'D47 value from SAT', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly) / 2, -2, 'D47 value from SST', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly) + len(d18Oc_HadCM_new_1PIC_columns_monthly) / 2, -2, 'd18Oc', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly) + len(d18Oc_HadCM_new_1PIC_columns_monthly) + len(precip_HadCM_new_1PIC_columns_monthly) / 2, -2, 'Precipitation', ha='center', va='center', fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_new_1PIC_columns_monthly) / 2, 'D47 value from SAT', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly) / 2, 'D47 value from SST', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly) + len(d18Oc_HadCM_new_1PIC_columns_monthly) / 2, 'd18Oc', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_new_1PIC_columns_monthly) + len(SST_D47_HadCM_new_1PIC_columns_monthly) + len(d18Oc_HadCM_new_1PIC_columns_monthly) + len(precip_HadCM_new_1PIC_columns_monthly) / 2, 'Precipitation', ha='center', va='center', rotation=90, fontsize=10)
plt.title("Normalized Combined Covariance Matrix (HadCM (new) 1x preindustrial pCO2)")
plt.show()
HadCM with 2x preindustrial pCO2¶
In [50]:
# Extract the relevant columns for SAT, SST D47, d18Oc, and precipitation
SAT_D47_HadCM_new_2PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_HadCM_new_2PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_HadCM_new_2PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_HadCM_new_2PIC_columns_monthly = [f"{month}_precip" for month in months]
# Combine the relevant columns into a single dataframe
combined_data_HadCM_new_2PIC_monthly = Lutetian_HadCM_new_2PIC_model[SAT_D47_HadCM_new_2PIC_columns_monthly + SST_D47_HadCM_new_2PIC_columns_monthly + d18Oc_HadCM_new_2PIC_columns_monthly + precip_HadCM_new_2PIC_columns_monthly]
# Calculate the covariance matrix for the combined data
cov_combined_HadCM_new_2PIC_monthly = np.cov(combined_data_HadCM_new_2PIC_monthly.dropna(), rowvar=False)
# Extract the covariance matrices for SAT D47, SST D47, d18Oc, and precipitation
cov_HadCM_new_2PIC_SAT_D47_monthly = cov_combined_HadCM_new_2PIC_monthly[:len(months), :len(months)]
cov_HadCM_new_2PIC_SST_D47_monthly = cov_combined_HadCM_new_2PIC_monthly[len(months):2*len(months), len(months):2*len(months)]
cov_HadCM_new_2PIC_d18Oc_monthly = cov_combined_HadCM_new_2PIC_monthly[2*len(months):3*len(months), 2*len(months):3*len(months)]
cov_HadCM_new_2PIC_precip_monthly = cov_combined_HadCM_new_2PIC_monthly[3*len(months):, 3*len(months):]
# Extract the cross-covariance matrices
cross_cov_HadCM_new_2PIC_SAT_SST_D47_monthly = cov_combined_HadCM_new_2PIC_monthly[:len(months), len(months):2*len(months)]
cross_cov_HadCM_new_2PIC_SAT_d18Oc_monthly = cov_combined_HadCM_new_2PIC_monthly[:len(months), 2*len(months):3*len(months)]
cross_cov_HadCM_new_2PIC_SAT_precip_monthly = cov_combined_HadCM_new_2PIC_monthly[:len(months), 3*len(months):]
cross_cov_HadCM_new_2PIC_SST_d18Oc_monthly = cov_combined_HadCM_new_2PIC_monthly[len(months):2*len(months), 2*len(months):3*len(months)]
cross_cov_HadCM_new_2PIC_SST_precip_monthly = cov_combined_HadCM_new_2PIC_monthly[len(months):2*len(months), 3*len(months):]
cross_cov_HadCM_new_2PIC_d18Oc_precip_monthly = cov_combined_HadCM_new_2PIC_monthly[2*len(months):3*len(months), 3*len(months):]
# Normalize each submatrix
normalized_cov_HadCM_new_2PIC_SAT_D47_monthly = normalize_matrix(cov_HadCM_new_2PIC_SAT_D47_monthly)
normalized_cov_HadCM_new_2PIC_SST_D47_monthly = normalize_matrix(cov_HadCM_new_2PIC_SST_D47_monthly)
normalized_cov_HadCM_new_2PIC_d18Oc_monthly = normalize_matrix(cov_HadCM_new_2PIC_d18Oc_monthly)
normalized_cov_HadCM_new_2PIC_precip_monthly = normalize_matrix(cov_HadCM_new_2PIC_precip_monthly)
# Normalize each cross-covariance matrix
normalized_cross_cov_HadCM_new_2PIC_SAT_SST_D47_monthly = normalize_matrix(cross_cov_HadCM_new_2PIC_SAT_SST_D47_monthly)
normalized_cross_cov_HadCM_new_2PIC_SAT_d18Oc_monthly = normalize_matrix(cross_cov_HadCM_new_2PIC_SAT_d18Oc_monthly)
normalized_cross_cov_HadCM_new_2PIC_SAT_precip_monthly = normalize_matrix(cross_cov_HadCM_new_2PIC_SAT_precip_monthly)
normalized_cross_cov_HadCM_new_2PIC_SST_d18Oc_monthly = normalize_matrix(cross_cov_HadCM_new_2PIC_SST_d18Oc_monthly)
normalized_cross_cov_HadCM_new_2PIC_SST_precip_monthly = normalize_matrix(cross_cov_HadCM_new_2PIC_SST_precip_monthly)
normalized_cross_cov_HadCM_new_2PIC_d18Oc_precip_monthly = normalize_matrix(cross_cov_HadCM_new_2PIC_d18Oc_precip_monthly)
# Combine the normalized submatrices into a single normalized covariance matrix
normalized_cov_combined_HadCM_new_2PIC_monthly = np.block([
[normalized_cov_HadCM_new_2PIC_SAT_D47_monthly, normalized_cross_cov_HadCM_new_2PIC_SAT_SST_D47_monthly, normalized_cross_cov_HadCM_new_2PIC_SAT_d18Oc_monthly, normalized_cross_cov_HadCM_new_2PIC_SAT_precip_monthly],
[normalized_cross_cov_HadCM_new_2PIC_SAT_SST_D47_monthly.T, normalized_cov_HadCM_new_2PIC_SST_D47_monthly, normalized_cross_cov_HadCM_new_2PIC_SST_d18Oc_monthly, normalized_cross_cov_HadCM_new_2PIC_SST_precip_monthly],
[normalized_cross_cov_HadCM_new_2PIC_SAT_d18Oc_monthly.T, normalized_cross_cov_HadCM_new_2PIC_SST_d18Oc_monthly.T, normalized_cov_HadCM_new_2PIC_d18Oc_monthly, normalized_cross_cov_HadCM_new_2PIC_d18Oc_precip_monthly],
[normalized_cross_cov_HadCM_new_2PIC_SAT_precip_monthly.T, normalized_cross_cov_HadCM_new_2PIC_SST_precip_monthly.T, normalized_cross_cov_HadCM_new_2PIC_d18Oc_precip_monthly.T, normalized_cov_HadCM_new_2PIC_precip_monthly]
])
# Plot the heatmap of the normalized combined covariance matrix
plt.figure(figsize=(12, 10))
sns.heatmap(
normalized_cov_combined_HadCM_new_2PIC_monthly,
annot=False,
fmt=".2f",
cmap="coolwarm",
center=0,
xticklabels=SAT_D47_HadCM_new_2PIC_columns_monthly + SST_D47_HadCM_new_2PIC_columns_monthly + d18Oc_HadCM_new_2PIC_columns_monthly + precip_HadCM_new_2PIC_columns_monthly,
yticklabels=SAT_D47_HadCM_new_2PIC_columns_monthly + SST_D47_HadCM_new_2PIC_columns_monthly + d18Oc_HadCM_new_2PIC_columns_monthly + precip_HadCM_new_2PIC_columns_monthly
)
# Add titles to the axes per parameter
plt.axvline(x=len(SAT_D47_HadCM_new_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly) + len(d18Oc_HadCM_new_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly) + len(d18Oc_HadCM_new_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
# Add parameter labels
plt.text(len(SAT_D47_HadCM_new_2PIC_columns_monthly) / 2, -2, 'D47 value from SAT', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly) / 2, -2, 'D47 value from SST', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly) + len(d18Oc_HadCM_new_2PIC_columns_monthly) / 2, -2, 'd18Oc', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly) + len(d18Oc_HadCM_new_2PIC_columns_monthly) + len(precip_HadCM_new_2PIC_columns_monthly) / 2, -2, 'Precipitation', ha='center', va='center', fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_new_2PIC_columns_monthly) / 2, 'D47 value from SAT', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly) / 2, 'D47 value from SST', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly) + len(d18Oc_HadCM_new_2PIC_columns_monthly) / 2, 'd18Oc', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_new_2PIC_columns_monthly) + len(SST_D47_HadCM_new_2PIC_columns_monthly) + len(d18Oc_HadCM_new_2PIC_columns_monthly) + len(precip_HadCM_new_2PIC_columns_monthly) / 2, 'Precipitation', ha='center', va='center', rotation=90, fontsize=10)
plt.title("Normalized Combined Covariance Matrix (HadCM (new) 2x preindustrial pCO2)")
plt.show()
HadCM with 1056 ppm pCO2¶
In [51]:
# Extract the relevant columns for SAT, SST D47, d18Oc, and precipitation
SAT_D47_HadCM_new_1056ppm_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_HadCM_new_1056ppm_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_HadCM_new_1056ppm_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_HadCM_new_1056ppm_columns_monthly = [f"{month}_precip" for month in months]
# Combine the relevant columns into a single dataframe
combined_data_HadCM_new_1056ppm_monthly = Lutetian_HadCM_new_1056ppm_model[SAT_D47_HadCM_new_1056ppm_columns_monthly + SST_D47_HadCM_new_1056ppm_columns_monthly + d18Oc_HadCM_new_1056ppm_columns_monthly + precip_HadCM_new_1056ppm_columns_monthly]
# Calculate the covariance matrix for the combined data
cov_combined_HadCM_new_1056ppm_monthly = np.cov(combined_data_HadCM_new_1056ppm_monthly.dropna(), rowvar=False)
# Extract the covariance matrices for SAT D47, SST D47, d18Oc, and precipitation
cov_HadCM_new_1056ppm_SAT_D47_monthly = cov_combined_HadCM_new_1056ppm_monthly[:len(months), :len(months)]
cov_HadCM_new_1056ppm_SST_D47_monthly = cov_combined_HadCM_new_1056ppm_monthly[len(months):2*len(months), len(months):2*len(months)]
cov_HadCM_new_1056ppm_d18Oc_monthly = cov_combined_HadCM_new_1056ppm_monthly[2*len(months):3*len(months), 2*len(months):3*len(months)]
cov_HadCM_new_1056ppm_precip_monthly = cov_combined_HadCM_new_1056ppm_monthly[3*len(months):, 3*len(months):]
# Extract the cross-covariance matrices
cross_cov_HadCM_new_1056ppm_SAT_SST_D47_monthly = cov_combined_HadCM_new_1056ppm_monthly[:len(months), len(months):2*len(months)]
cross_cov_HadCM_new_1056ppm_SAT_d18Oc_monthly = cov_combined_HadCM_new_1056ppm_monthly[:len(months), 2*len(months):3*len(months)]
cross_cov_HadCM_new_1056ppm_SAT_precip_monthly = cov_combined_HadCM_new_1056ppm_monthly[:len(months), 3*len(months):]
cross_cov_HadCM_new_1056ppm_SST_d18Oc_monthly = cov_combined_HadCM_new_1056ppm_monthly[len(months):2*len(months), 2*len(months):3*len(months)]
cross_cov_HadCM_new_1056ppm_SST_precip_monthly = cov_combined_HadCM_new_1056ppm_monthly[len(months):2*len(months), 3*len(months):]
cross_cov_HadCM_new_1056ppm_d18Oc_precip_monthly = cov_combined_HadCM_new_1056ppm_monthly[2*len(months):3*len(months), 3*len(months):]
# Normalize each submatrix
normalized_cov_HadCM_new_1056ppm_SAT_D47_monthly = normalize_matrix(cov_HadCM_new_1056ppm_SAT_D47_monthly)
normalized_cov_HadCM_new_1056ppm_SST_D47_monthly = normalize_matrix(cov_HadCM_new_1056ppm_SST_D47_monthly)
normalized_cov_HadCM_new_1056ppm_d18Oc_monthly = normalize_matrix(cov_HadCM_new_1056ppm_d18Oc_monthly)
normalized_cov_HadCM_new_1056ppm_precip_monthly = normalize_matrix(cov_HadCM_new_1056ppm_precip_monthly)
# Normalize each cross-covariance matrix
normalized_cross_cov_HadCM_new_1056ppm_SAT_SST_D47_monthly = normalize_matrix(cross_cov_HadCM_new_1056ppm_SAT_SST_D47_monthly)
normalized_cross_cov_HadCM_new_1056ppm_SAT_d18Oc_monthly = normalize_matrix(cross_cov_HadCM_new_1056ppm_SAT_d18Oc_monthly)
normalized_cross_cov_HadCM_new_1056ppm_SAT_precip_monthly = normalize_matrix(cross_cov_HadCM_new_1056ppm_SAT_precip_monthly)
normalized_cross_cov_HadCM_new_1056ppm_SST_d18Oc_monthly = normalize_matrix(cross_cov_HadCM_new_1056ppm_SST_d18Oc_monthly)
normalized_cross_cov_HadCM_new_1056ppm_SST_precip_monthly = normalize_matrix(cross_cov_HadCM_new_1056ppm_SST_precip_monthly)
normalized_cross_cov_HadCM_new_1056ppm_d18Oc_precip_monthly = normalize_matrix(cross_cov_HadCM_new_1056ppm_d18Oc_precip_monthly)
# Combine the normalized submatrices into a single normalized covariance matrix
normalized_cov_combined_HadCM_new_1056ppm_monthly = np.block([
[normalized_cov_HadCM_new_1056ppm_SAT_D47_monthly, normalized_cross_cov_HadCM_new_1056ppm_SAT_SST_D47_monthly, normalized_cross_cov_HadCM_new_1056ppm_SAT_d18Oc_monthly, normalized_cross_cov_HadCM_new_1056ppm_SAT_precip_monthly],
[normalized_cross_cov_HadCM_new_1056ppm_SAT_SST_D47_monthly.T, normalized_cov_HadCM_new_1056ppm_SST_D47_monthly, normalized_cross_cov_HadCM_new_1056ppm_SST_d18Oc_monthly, normalized_cross_cov_HadCM_new_1056ppm_SST_precip_monthly],
[normalized_cross_cov_HadCM_new_1056ppm_SAT_d18Oc_monthly.T, normalized_cross_cov_HadCM_new_1056ppm_SST_d18Oc_monthly.T, normalized_cov_HadCM_new_1056ppm_d18Oc_monthly, normalized_cross_cov_HadCM_new_1056ppm_d18Oc_precip_monthly],
[normalized_cross_cov_HadCM_new_1056ppm_SAT_precip_monthly.T, normalized_cross_cov_HadCM_new_1056ppm_SST_precip_monthly.T, normalized_cross_cov_HadCM_new_1056ppm_d18Oc_precip_monthly.T, normalized_cov_HadCM_new_1056ppm_precip_monthly]
])
# Plot the heatmap of the normalized combined covariance matrix
plt.figure(figsize=(12, 10))
sns.heatmap(
normalized_cov_combined_HadCM_new_1056ppm_monthly,
annot=False,
fmt=".2f",
cmap="coolwarm",
center=0,
xticklabels=SAT_D47_HadCM_new_1056ppm_columns_monthly + SST_D47_HadCM_new_1056ppm_columns_monthly + d18Oc_HadCM_new_1056ppm_columns_monthly + precip_HadCM_new_1056ppm_columns_monthly,
yticklabels=SAT_D47_HadCM_new_1056ppm_columns_monthly + SST_D47_HadCM_new_1056ppm_columns_monthly + d18Oc_HadCM_new_1056ppm_columns_monthly + precip_HadCM_new_1056ppm_columns_monthly
)
# Add titles to the axes per parameter
plt.axvline(x=len(SAT_D47_HadCM_new_1056ppm_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly) + len(d18Oc_HadCM_new_1056ppm_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_1056ppm_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly) + len(d18Oc_HadCM_new_1056ppm_columns_monthly), color='black', linestyle='--', linewidth=1)
# Add parameter labels
plt.text(len(SAT_D47_HadCM_new_1056ppm_columns_monthly) / 2, -2, 'D47 value from SAT', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly) / 2, -2, 'D47 value from SST', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly) + len(d18Oc_HadCM_new_1056ppm_columns_monthly) / 2, -2, 'd18Oc', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly) + len(d18Oc_HadCM_new_1056ppm_columns_monthly) + len(precip_HadCM_new_1056ppm_columns_monthly) / 2, -2, 'Precipitation', ha='center', va='center', fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_new_1056ppm_columns_monthly) / 2, 'D47 value from SAT', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly) / 2, 'D47 value from SST', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly) + len(d18Oc_HadCM_new_1056ppm_columns_monthly) / 2, 'd18Oc', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_new_1056ppm_columns_monthly) + len(SST_D47_HadCM_new_1056ppm_columns_monthly) + len(d18Oc_HadCM_new_1056ppm_columns_monthly) + len(precip_HadCM_new_1056ppm_columns_monthly) / 2, 'Precipitation', ha='center', va='center', rotation=90, fontsize=10)
plt.title("Normalized Combined Covariance Matrix (CESM 2x preindustrial pCO2)")
plt.show()
HadCM (old) with 2x preindustrial pCO2¶
In [52]:
# Extract the relevant columns for SAT, SST D47, d18Oc, and precipitation
SAT_D47_HadCM_old_2PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_HadCM_old_2PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_HadCM_old_2PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_HadCM_old_2PIC_columns_monthly = [f"{month}_precip" for month in months]
# Combine the relevant columns into a single dataframe
combined_data_HadCM_old_2PIC_monthly = Lutetian_HadCM_old_2PIC_model[SAT_D47_HadCM_old_2PIC_columns_monthly + SST_D47_HadCM_old_2PIC_columns_monthly + d18Oc_HadCM_old_2PIC_columns_monthly + precip_HadCM_old_2PIC_columns_monthly]
# Calculate the covariance matrix for the combined data
cov_combined_HadCM_old_2PIC_monthly = np.cov(combined_data_HadCM_old_2PIC_monthly.dropna(), rowvar=False)
# Extract the covariance matrices for SAT D47, SST D47, d18Oc, and precipitation
cov_HadCM_old_2PIC_SAT_D47_monthly = cov_combined_HadCM_old_2PIC_monthly[:len(months), :len(months)]
cov_HadCM_old_2PIC_SST_D47_monthly = cov_combined_HadCM_old_2PIC_monthly[len(months):2*len(months), len(months):2*len(months)]
cov_HadCM_old_2PIC_d18Oc_monthly = cov_combined_HadCM_old_2PIC_monthly[2*len(months):3*len(months), 2*len(months):3*len(months)]
cov_HadCM_old_2PIC_precip_monthly = cov_combined_HadCM_old_2PIC_monthly[3*len(months):, 3*len(months):]
# Extract the cross-covariance matrices
cross_cov_HadCM_old_2PIC_SAT_SST_D47_monthly = cov_combined_HadCM_old_2PIC_monthly[:len(months), len(months):2*len(months)]
cross_cov_HadCM_old_2PIC_SAT_d18Oc_monthly = cov_combined_HadCM_old_2PIC_monthly[:len(months), 2*len(months):3*len(months)]
cross_cov_HadCM_old_2PIC_SAT_precip_monthly = cov_combined_HadCM_old_2PIC_monthly[:len(months), 3*len(months):]
cross_cov_HadCM_old_2PIC_SST_d18Oc_monthly = cov_combined_HadCM_old_2PIC_monthly[len(months):2*len(months), 2*len(months):3*len(months)]
cross_cov_HadCM_old_2PIC_SST_precip_monthly = cov_combined_HadCM_old_2PIC_monthly[len(months):2*len(months), 3*len(months):]
cross_cov_HadCM_old_2PIC_d18Oc_precip_monthly = cov_combined_HadCM_old_2PIC_monthly[2*len(months):3*len(months), 3*len(months):]
# Normalize each submatrix
normalized_cov_HadCM_old_2PIC_SAT_D47_monthly = normalize_matrix(cov_HadCM_old_2PIC_SAT_D47_monthly)
normalized_cov_HadCM_old_2PIC_SST_D47_monthly = normalize_matrix(cov_HadCM_old_2PIC_SST_D47_monthly)
normalized_cov_HadCM_old_2PIC_d18Oc_monthly = normalize_matrix(cov_HadCM_old_2PIC_d18Oc_monthly)
normalized_cov_HadCM_old_2PIC_precip_monthly = normalize_matrix(cov_HadCM_old_2PIC_precip_monthly)
# Normalize each cross-covariance matrix
normalized_cross_cov_HadCM_old_2PIC_SAT_SST_D47_monthly = normalize_matrix(cross_cov_HadCM_old_2PIC_SAT_SST_D47_monthly)
normalized_cross_cov_HadCM_old_2PIC_SAT_d18Oc_monthly = normalize_matrix(cross_cov_HadCM_old_2PIC_SAT_d18Oc_monthly)
normalized_cross_cov_HadCM_old_2PIC_SAT_precip_monthly = normalize_matrix(cross_cov_HadCM_old_2PIC_SAT_precip_monthly)
normalized_cross_cov_HadCM_old_2PIC_SST_d18Oc_monthly = normalize_matrix(cross_cov_HadCM_old_2PIC_SST_d18Oc_monthly)
normalized_cross_cov_HadCM_old_2PIC_SST_precip_monthly = normalize_matrix(cross_cov_HadCM_old_2PIC_SST_precip_monthly)
normalized_cross_cov_HadCM_old_2PIC_d18Oc_precip_monthly = normalize_matrix(cross_cov_HadCM_old_2PIC_d18Oc_precip_monthly)
# Combine the normalized submatrices into a single normalized covariance matrix
normalized_cov_combined_HadCM_old_2PIC_monthly = np.block([
[normalized_cov_HadCM_old_2PIC_SAT_D47_monthly, normalized_cross_cov_HadCM_old_2PIC_SAT_SST_D47_monthly, normalized_cross_cov_HadCM_old_2PIC_SAT_d18Oc_monthly, normalized_cross_cov_HadCM_old_2PIC_SAT_precip_monthly],
[normalized_cross_cov_HadCM_old_2PIC_SAT_SST_D47_monthly.T, normalized_cov_HadCM_old_2PIC_SST_D47_monthly, normalized_cross_cov_HadCM_old_2PIC_SST_d18Oc_monthly, normalized_cross_cov_HadCM_old_2PIC_SST_precip_monthly],
[normalized_cross_cov_HadCM_old_2PIC_SAT_d18Oc_monthly.T, normalized_cross_cov_HadCM_old_2PIC_SST_d18Oc_monthly.T, normalized_cov_HadCM_old_2PIC_d18Oc_monthly, normalized_cross_cov_HadCM_old_2PIC_d18Oc_precip_monthly],
[normalized_cross_cov_HadCM_old_2PIC_SAT_precip_monthly.T, normalized_cross_cov_HadCM_old_2PIC_SST_precip_monthly.T, normalized_cross_cov_HadCM_old_2PIC_d18Oc_precip_monthly.T, normalized_cov_HadCM_old_2PIC_precip_monthly]
])
# Plot the heatmap of the normalized combined covariance matrix
plt.figure(figsize=(12, 10))
sns.heatmap(
normalized_cov_combined_HadCM_old_2PIC_monthly,
annot=False,
fmt=".2f",
cmap="coolwarm",
center=0,
xticklabels=SAT_D47_HadCM_old_2PIC_columns_monthly + SST_D47_HadCM_old_2PIC_columns_monthly + d18Oc_HadCM_old_2PIC_columns_monthly + precip_HadCM_old_2PIC_columns_monthly,
yticklabels=SAT_D47_HadCM_old_2PIC_columns_monthly + SST_D47_HadCM_old_2PIC_columns_monthly + d18Oc_HadCM_old_2PIC_columns_monthly + precip_HadCM_old_2PIC_columns_monthly
)
# Add titles to the axes per parameter
plt.axvline(x=len(SAT_D47_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
# Add parameter labels
plt.text(len(SAT_D47_HadCM_old_2PIC_columns_monthly) / 2, -2, 'D47 value from SAT', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) / 2, -2, 'D47 value from SST', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly) / 2, -2, 'd18Oc', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly) + len(precip_HadCM_old_2PIC_columns_monthly) / 2, -2, 'Precipitation', ha='center', va='center', fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_old_2PIC_columns_monthly) / 2, 'D47 value from SAT', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) / 2, 'D47 value from SST', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly) / 2, 'd18Oc', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly) + len(precip_HadCM_old_2PIC_columns_monthly) / 2, 'Precipitation', ha='center', va='center', rotation=90, fontsize=10)
plt.title("Normalized Combined Covariance Matrix (HadCM (new) 1x preindustrial pCO2)")
plt.show()
HadCM (old) with 4x preindustrial pCO2¶
In [53]:
# Extract the relevant columns for SAT, SST D47, d18Oc, and precipitation
SAT_D47_HadCM_old_4PIC_columns_monthly = [f"{month}_SAT_D47" for month in months]
SST_D47_HadCM_old_4PIC_columns_monthly = [f"{month}_SST_D47" for month in months]
d18Oc_HadCM_old_4PIC_columns_monthly = [f"{month}_d18Oc" for month in months]
precip_HadCM_old_4PIC_columns_monthly = [f"{month}_precip" for month in months]
# Combine the relevant columns into a single dataframe
combined_data_HadCM_old_4PIC_monthly = Lutetian_HadCM_old_4PIC_model[SAT_D47_HadCM_old_4PIC_columns_monthly + SST_D47_HadCM_old_4PIC_columns_monthly + d18Oc_HadCM_old_4PIC_columns_monthly + precip_HadCM_old_4PIC_columns_monthly]
# Calculate the covariance matrix for the combined data
cov_combined_HadCM_old_4PIC_monthly = np.cov(combined_data_HadCM_old_4PIC_monthly.dropna(), rowvar=False)
# Extract the covariance matrices for SAT D47, SST D47, d18Oc, and precipitation
cov_HadCM_old_4PIC_SAT_D47_monthly = cov_combined_HadCM_old_4PIC_monthly[:len(months), :len(months)]
cov_HadCM_old_4PIC_SST_D47_monthly = cov_combined_HadCM_old_4PIC_monthly[len(months):2*len(months), len(months):2*len(months)]
cov_HadCM_old_4PIC_d18Oc_monthly = cov_combined_HadCM_old_4PIC_monthly[2*len(months):3*len(months), 2*len(months):3*len(months)]
cov_HadCM_old_4PIC_precip_monthly = cov_combined_HadCM_old_4PIC_monthly[3*len(months):, 3*len(months):]
# Extract the cross-covariance matrices
cross_cov_HadCM_old_4PIC_SAT_SST_D47_monthly = cov_combined_HadCM_old_4PIC_monthly[:len(months), len(months):2*len(months)]
cross_cov_HadCM_old_4PIC_SAT_d18Oc_monthly = cov_combined_HadCM_old_4PIC_monthly[:len(months), 2*len(months):3*len(months)]
cross_cov_HadCM_old_4PIC_SAT_precip_monthly = cov_combined_HadCM_old_4PIC_monthly[:len(months), 3*len(months):]
cross_cov_HadCM_old_4PIC_SST_d18Oc_monthly = cov_combined_HadCM_old_4PIC_monthly[len(months):2*len(months), 2*len(months):3*len(months)]
cross_cov_HadCM_old_4PIC_SST_precip_monthly = cov_combined_HadCM_old_4PIC_monthly[len(months):2*len(months), 3*len(months):]
cross_cov_HadCM_old_4PIC_d18Oc_precip_monthly = cov_combined_HadCM_old_4PIC_monthly[2*len(months):3*len(months), 3*len(months):]
# Normalize each submatrix
normalized_cov_HadCM_old_4PIC_SAT_D47_monthly = normalize_matrix(cov_HadCM_old_4PIC_SAT_D47_monthly)
normalized_cov_HadCM_old_4PIC_SST_D47_monthly = normalize_matrix(cov_HadCM_old_4PIC_SST_D47_monthly)
normalized_cov_HadCM_old_4PIC_d18Oc_monthly = normalize_matrix(cov_HadCM_old_4PIC_d18Oc_monthly)
normalized_cov_HadCM_old_4PIC_precip_monthly = normalize_matrix(cov_HadCM_old_4PIC_precip_monthly)
# Normalize each cross-covariance matrix
normalized_cross_cov_HadCM_old_4PIC_SAT_SST_D47_monthly = normalize_matrix(cross_cov_HadCM_old_4PIC_SAT_SST_D47_monthly)
normalized_cross_cov_HadCM_old_4PIC_SAT_d18Oc_monthly = normalize_matrix(cross_cov_HadCM_old_4PIC_SAT_d18Oc_monthly)
normalized_cross_cov_HadCM_old_4PIC_SAT_precip_monthly = normalize_matrix(cross_cov_HadCM_old_4PIC_SAT_precip_monthly)
normalized_cross_cov_HadCM_old_4PIC_SST_d18Oc_monthly = normalize_matrix(cross_cov_HadCM_old_4PIC_SST_d18Oc_monthly)
normalized_cross_cov_HadCM_old_4PIC_SST_precip_monthly = normalize_matrix(cross_cov_HadCM_old_4PIC_SST_precip_monthly)
normalized_cross_cov_HadCM_old_4PIC_d18Oc_precip_monthly = normalize_matrix(cross_cov_HadCM_old_4PIC_d18Oc_precip_monthly)
# Combine the normalized submatrices into a single normalized covariance matrix
normalized_cov_combined_HadCM_old_4PIC_monthly = np.block([
[normalized_cov_HadCM_old_4PIC_SAT_D47_monthly, normalized_cross_cov_HadCM_old_4PIC_SAT_SST_D47_monthly, normalized_cross_cov_HadCM_old_4PIC_SAT_d18Oc_monthly, normalized_cross_cov_HadCM_old_4PIC_SAT_precip_monthly],
[normalized_cross_cov_HadCM_old_4PIC_SAT_SST_D47_monthly.T, normalized_cov_HadCM_old_4PIC_SST_D47_monthly, normalized_cross_cov_HadCM_old_4PIC_SST_d18Oc_monthly, normalized_cross_cov_HadCM_old_4PIC_SST_precip_monthly],
[normalized_cross_cov_HadCM_old_4PIC_SAT_d18Oc_monthly.T, normalized_cross_cov_HadCM_old_4PIC_SST_d18Oc_monthly.T, normalized_cov_HadCM_old_4PIC_d18Oc_monthly, normalized_cross_cov_HadCM_old_4PIC_d18Oc_precip_monthly],
[normalized_cross_cov_HadCM_old_4PIC_SAT_precip_monthly.T, normalized_cross_cov_HadCM_old_4PIC_SST_precip_monthly.T, normalized_cross_cov_HadCM_old_4PIC_d18Oc_precip_monthly.T, normalized_cov_HadCM_old_4PIC_precip_monthly]
])
# Plot the heatmap of the normalized combined covariance matrix
plt.figure(figsize=(12, 10))
sns.heatmap(
normalized_cov_combined_HadCM_old_4PIC_monthly,
annot=False,
fmt=".2f",
cmap="coolwarm",
center=0,
xticklabels=SAT_D47_HadCM_old_4PIC_columns_monthly + SST_D47_HadCM_old_4PIC_columns_monthly + d18Oc_HadCM_old_4PIC_columns_monthly + precip_HadCM_old_4PIC_columns_monthly,
yticklabels=SAT_D47_HadCM_old_4PIC_columns_monthly + SST_D47_HadCM_old_4PIC_columns_monthly + d18Oc_HadCM_old_4PIC_columns_monthly + precip_HadCM_old_4PIC_columns_monthly
)
# Add titles to the axes per parameter
plt.axvline(x=len(SAT_D47_HadCM_old_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly) + len(d18Oc_HadCM_old_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_old_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly) + len(d18Oc_HadCM_old_4PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
# Add parameter labels
plt.text(len(SAT_D47_HadCM_old_4PIC_columns_monthly) / 2, -2, 'D47 value from SAT', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly) / 2, -2, 'D47 value from SST', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly) + len(d18Oc_HadCM_old_4PIC_columns_monthly) / 2, -2, 'd18Oc', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly) + len(d18Oc_HadCM_old_4PIC_columns_monthly) + len(precip_HadCM_old_4PIC_columns_monthly) / 2, -2, 'Precipitation', ha='center', va='center', fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_old_4PIC_columns_monthly) / 2, 'D47 value from SAT', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly) / 2, 'D47 value from SST', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly) + len(d18Oc_HadCM_old_4PIC_columns_monthly) / 2, 'd18Oc', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_old_4PIC_columns_monthly) + len(SST_D47_HadCM_old_4PIC_columns_monthly) + len(d18Oc_HadCM_old_4PIC_columns_monthly) + len(precip_HadCM_old_4PIC_columns_monthly) / 2, 'Precipitation', ha='center', va='center', rotation=90, fontsize=10)
plt.title("Normalized Combined Covariance Matrix (HadCM (new) 1x preindustrial pCO2)")
plt.show()
Test the difference between 2x and 4x preindustrial pCO2¶
In [54]:
# Calculate the difference between the two normalized covariance matrices
normalized_cov_combined_2_4_PIC_diff_monthly = normalized_cov_combined_CESM_2PIC_monthly - normalized_cov_combined_CESM_4PIC_monthly
# Plot the heatmap of the normalized combined covariance matrix
plt.figure(figsize=(12, 10))
sns.heatmap(
normalized_cov_combined_2_4_PIC_diff_monthly,
annot=False,
fmt=".2f",
cmap="coolwarm",
center=0,
xticklabels=SAT_D47_CESM_2PIC_columns_monthly + SST_D47_CESM_2PIC_columns_monthly + d18Oc_CESM_2PIC_columns_monthly + precip_CESM_2PIC_columns_monthly,
yticklabels=SAT_D47_CESM_2PIC_columns_monthly + SST_D47_CESM_2PIC_columns_monthly + d18Oc_CESM_2PIC_columns_monthly + precip_CESM_2PIC_columns_monthly
)
# Add titles to the axes per parameter
plt.axvline(x=len(SAT_D47_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
# Add parameter labels
plt.text(len(SAT_D47_CESM_2PIC_columns_monthly) / 2, -2, 'D47 value from SAT', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) / 2, -2, 'D47 value from SST', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly) / 2, -2, 'd18Oc', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly) + len(precip_CESM_2PIC_columns_monthly) / 2, -2, 'Precipitation', ha='center', va='center', fontsize=10)
plt.text(-7, len(SAT_D47_CESM_2PIC_columns_monthly) / 2, 'D47 value from SAT', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) / 2, 'D47 value from SST', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly) / 2, 'd18Oc', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_CESM_2PIC_columns_monthly) + len(SST_D47_CESM_2PIC_columns_monthly) + len(d18Oc_CESM_2PIC_columns_monthly) + len(precip_CESM_2PIC_columns_monthly) / 2, 'Precipitation', ha='center', va='center', rotation=90, fontsize=10)
plt.title("Normalized difference between covariance Matrices (CESM 2x - 4x preindustrial pCO2)")
plt.show()
Test the difference between old and new HadCM model at 2x preindustrial pCO2¶
In [55]:
# Calculate the difference between the two normalized covariance matrices
normalized_cov_combined_HadCM_old_new_PIC_diff_monthly = normalized_cov_combined_HadCM_old_2PIC_monthly - normalized_cov_combined_HadCM_new_2PIC_monthly
# Plot the heatmap of the normalized combined covariance matrix
plt.figure(figsize=(12, 10))
sns.heatmap(
normalized_cov_combined_HadCM_old_new_PIC_diff_monthly,
annot=False,
fmt=".2f",
cmap="coolwarm",
center=0,
xticklabels=SAT_D47_HadCM_old_2PIC_columns_monthly + SST_D47_HadCM_old_2PIC_columns_monthly + d18Oc_HadCM_old_2PIC_columns_monthly + precip_HadCM_old_2PIC_columns_monthly,
yticklabels=SAT_D47_HadCM_old_2PIC_columns_monthly + SST_D47_HadCM_old_2PIC_columns_monthly + d18Oc_HadCM_old_2PIC_columns_monthly + precip_HadCM_old_2PIC_columns_monthly
)
# Add titles to the axes per parameter
plt.axvline(x=len(SAT_D47_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axvline(x=len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
plt.axhline(y=len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly), color='black', linestyle='--', linewidth=1)
# Add parameter labels
plt.text(len(SAT_D47_HadCM_old_2PIC_columns_monthly) / 2, -2, 'D47 value from SAT', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) / 2, -2, 'D47 value from SST', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly) / 2, -2, 'd18Oc', ha='center', va='center', fontsize=10)
plt.text(len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly) + len(precip_HadCM_old_2PIC_columns_monthly) / 2, -2, 'Precipitation', ha='center', va='center', fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_old_2PIC_columns_monthly) / 2, 'D47 value from SAT', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) / 2, 'D47 value from SST', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly) / 2, 'd18Oc', ha='center', va='center', rotation=90, fontsize=10)
plt.text(-7, len(SAT_D47_HadCM_old_2PIC_columns_monthly) + len(SST_D47_HadCM_old_2PIC_columns_monthly) + len(d18Oc_HadCM_old_2PIC_columns_monthly) + len(precip_HadCM_old_2PIC_columns_monthly) / 2, 'Precipitation', ha='center', va='center', rotation=90, fontsize=10)
plt.title("Normalized difference between covariance Matrices (CESM 2x - 4x preindustrial pCO2)")
plt.show()
Create combined monthly state vector¶
In [56]:
# Combine the prior means of D47 and SAT into a single state vector
mu_prior_CESM_4PIC_monthly_combined = np.concatenate((mu_prior_CESM_4PIC_SST_D47_monthly, mu_prior_CESM_4PIC_SAT_D47_monthly, mu_prior_CESM_4PIC_d18Oc_monthly, mu_prior_CESM_4PIC_precip_monthly))
mu_prior_CESM_2PIC_monthly_combined = np.concatenate((mu_prior_CESM_2PIC_SST_D47_monthly, mu_prior_CESM_2PIC_SAT_D47_monthly, mu_prior_CESM_2PIC_d18Oc_monthly, mu_prior_CESM_2PIC_precip_monthly))
mu_prior_HadCM_new_1PIC_monthly_combined = np.concatenate((mu_prior_HadCM_new_1PIC_SST_D47_monthly, mu_prior_HadCM_new_1PIC_SAT_D47_monthly, mu_prior_HadCM_new_1PIC_d18Oc_monthly, mu_prior_HadCM_new_1PIC_precip_monthly))
mu_prior_HadCM_new_2PIC_monthly_combined = np.concatenate((mu_prior_HadCM_new_2PIC_SST_D47_monthly, mu_prior_HadCM_new_2PIC_SAT_D47_monthly, mu_prior_HadCM_new_2PIC_d18Oc_monthly, mu_prior_HadCM_new_2PIC_precip_monthly))
mu_prior_HadCM_new_1056ppm_monthly_combined = np.concatenate((mu_prior_HadCM_new_1056ppm_SST_D47_monthly, mu_prior_HadCM_new_1056ppm_SAT_D47_monthly, mu_prior_HadCM_new_1056ppm_d18Oc_monthly, mu_prior_HadCM_new_1056ppm_precip_monthly))
mu_prior_HadCM_old_2PIC_monthly_combined = np.concatenate((mu_prior_HadCM_old_2PIC_SST_D47_monthly, mu_prior_HadCM_old_2PIC_SAT_D47_monthly, mu_prior_HadCM_old_2PIC_d18Oc_monthly, mu_prior_HadCM_old_2PIC_precip_monthly))
mu_prior_HadCM_old_4PIC_monthly_combined = np.concatenate((mu_prior_HadCM_old_4PIC_SST_D47_monthly, mu_prior_HadCM_old_4PIC_SAT_D47_monthly, mu_prior_HadCM_old_4PIC_d18Oc_monthly, mu_prior_HadCM_old_4PIC_precip_monthly))
# Combine the covariance matrices of D47 values of SST and SAT, including the cross-covariance
cov_prior_CESM_4PIC_monthly_combined = cov_combined_CESM_4PIC_monthly.copy()
cov_prior_CESM_2PIC_monthly_combined = cov_combined_CESM_2PIC_monthly.copy()
cov_prior_HadCM_new_1PIC_monthly_combined = cov_combined_HadCM_new_1PIC_monthly.copy()
cov_prior_HadCM_new_2PIC_monthly_combined = cov_combined_HadCM_new_2PIC_monthly.copy()
cov_prior_HadCM_new_1056ppm_monthly_combined = cov_combined_HadCM_new_1056ppm_monthly.copy()
cov_prior_HadCM_old_2PIC_monthly_combined = cov_combined_HadCM_old_2PIC_monthly.copy()
cov_prior_HadCM_old_4PIC_monthly_combined = cov_combined_HadCM_old_4PIC_monthly.copy()
In [57]:
# Load seasonal measurements and format them into a dictionary
# This is precompiled seasonal data per specimen and therefore does not come with a time uncertainty
Lutetian_seasonally_aggregated_data = pd.read_csv('Lutetian case/D47_season_data_calc.csv') # Load the data for seasonal averages
Lutetian_seasonally_aggregated_data_dict = Lutetian_seasonally_aggregated_data.to_dict('records') # Convert to dictionary with column headers as keys
# Add an entry for the time uncertainty (which is always zero in this case, because data is already aggregated monthly)
for record in Lutetian_seasonally_aggregated_data_dict:
record["Season_err"] = 0 # Set the time uncertainty to zero
record["D47_se"] = record["D47_SD"] / np.sqrt(record["count"]) # Calculate the standard error of the D47 value
print(Lutetian_seasonally_aggregated_data_dict[0]) # Print to check the structure of the data
{'Season': 'summer', 'Whorl...P.or.T': 'AW', 'X': 'AX', 'D47_mean': 0.589860492, 'D47_SD': 0.042653301, 'count': 62, 'd18O': -2.150527044, 'd18O_SD': 0.312787802, 'T': 27.892776, 'CL95': 0.010920335, 'CL95_T': 3.824099323, 'd18Osw': -0.27016391, 'DOY': 203.6572, 'Tmin': 24.20918351, 'Tmax': 31.71674359, 'dwmin': -1.11891794, 'dwmax': 0.610934613, 'Season_err': 0, 'D47_se': 0.005416974643977352}
Raw data at the sample level¶
In [58]:
# Load measurements and format them into a dictionary
# These are the actual individual D47 and d18Oc measurements and ShellChron outcomes and thus come with a time uncertainty which can be propagated.
Lutetian_D47_data = pd.read_csv('Lutetian case/Campanile_sample_data_calc2.csv') # Load data for individual D47 and d18Oc measurements and ShellChron outcomes
Lutetian_data_dict = Lutetian_D47_data.to_dict('records') # Convert to dictionary with column headers as keys
# Add an entry for the time uncertainty (which is always zero in this case, because there is no time uncertainty in the raw data)
for record in Lutetian_data_dict:
# Handle missing values and convert from days to months and seasons
shell_chron_doy_err = record.get("DOY_SD", np.nan) # Get value, default to NaN if missing
if pd.isna(shell_chron_doy_err): # Check if the value is NaN
record["Month_err"] = 0 # Set the time uncertainty to zero
record["Season_err"] = 0 # Set the time uncertainty to zero
record["no_err"] = 0 # Set the time uncertainty to zero
else:
record["Month_err"] = shell_chron_doy_err / 365 * 12 # Convert days to months
record["Season_err"] = shell_chron_doy_err / 365 * 4 # Convert days to seasons
record["no_err"] = 0 # Set the time uncertainty to zero for no error
# Assign the D47 value and its standard deviation
record["D47_SD"] = 0.029 # Assign external standard deviation to the D47 value (based on reproducibility of IAEA-C2 measurements)
record["season_score"] = np.floor(((record["DOY"] + 45) % 365) / 365 * 4) # Calculate the season score from DOY value (winter = 0, spring = 1, summer = 2, autumn = 3). Shift two months to align with the seasons defined in paper.
record["month_score"] = np.floor(((record["DOY"]) % 365) / 365 * 12) # Calculate the month score from DOY value (January = 0, February = 1, ..., December = 11).
print(Lutetian_data_dict[0]) # Print to check the structure of the data
{'ID': 'AB002', 'D': 5.0, 'Run': nan, 'Row': nan, 'Sample.intensity': nan, 'X49.parameter': nan, 'D47_raw': nan, 'D47_SD': 0.029, 'D47_final': nan, 'Temperature': nan, 'd18O': -1.5, 'd13C': 2.15, 'Whorl': nan, 'sample_nr': nan, 'Year': nan, 'season_manual': nan, 'd18O_SD': 0.1, 'day': 145.316271, 'DOY_SD': nan, 'season_label': nan, 'T_d18O': nan, 'DOY': 145.316271, 'Season': nan, 'Month_err': 0, 'Season_err': 0, 'no_err': 0, 'season_score': 2.0, 'month_score': 4.0}
Aggregate proxy data to monthly bins¶
In [59]:
# Aggregate and summarize proxy data per month, tracking mean and propagated SE for D47 and d18O separately
monthly_agg = []
for month in range(12):
month_records = [record for record in Lutetian_data_dict if int(record["month_score"]) == month]
entry = {
"month_score": month,
"D47_mean": np.nanmean([rec.get("D47_final") for rec in month_records if not pd.isna(rec.get("D47_final"))]),
"D47_SD": np.sqrt(np.nansum([rec.get("D47_SD", np.nan) ** 2 for rec in month_records if not pd.isna(rec.get("D47_SD")) and not pd.isna(rec.get("D47_final"))])) / max(1, len([rec for rec in month_records if not pd.isna(rec.get("D47_SD")) and not pd.isna(rec.get("D47_final"))])),
"d18O": np.nanmean([rec.get("d18O") for rec in month_records if not pd.isna(rec.get("d18O"))]),
"d18O_SD": np.sqrt(np.nansum([rec.get("d18O_SD", np.nan) ** 2 for rec in month_records if not pd.isna(rec.get("d18O_SD")) and not pd.isna(rec.get("d18O"))])) / max(1, len([rec for rec in month_records if not pd.isna(rec.get("d18O_SD")) and not pd.isna(rec.get("d18O"))])),
"Month_err": 0
}
monthly_agg.append(entry)
Lutetian_data_monthly_aggregated_df = pd.DataFrame(monthly_agg)
Lutetian_data_monthly_aggregated_dict = Lutetian_data_monthly_aggregated_df.to_dict("records")
print(Lutetian_data_monthly_aggregated_dict[0]) # Print to check the structure of the data
print(Lutetian_data_monthly_aggregated_dict[0]) # Print to check the structure of the data
{'month_score': 0, 'D47_mean': 0.6315000000000001, 'D47_SD': 0.0145, 'd18O': 0.016000000000000014, 'd18O_SD': 0.0447213595499958, 'Month_err': 0}
{'month_score': 0, 'D47_mean': 0.6315000000000001, 'D47_SD': 0.0145, 'd18O': 0.016000000000000014, 'd18O_SD': 0.0447213595499958, 'Month_err': 0}
C:\Users\nwi213\AppData\Local\Temp\ipykernel_4724\1428035188.py:7: RuntimeWarning: Mean of empty slice
"D47_mean": np.nanmean([rec.get("D47_final") for rec in month_records if not pd.isna(rec.get("D47_final"))]),
Prepare measurement and observation matrices¶
Define a wrapped normal distribution to allow uncertainty in the time domain to flow around the year¶
In [60]:
# Function to calculate wrapped normal distribution weights
def wrapped_normal_pdf(x, mean, sd, num_bins):
# Calculate the normal PDF for each bin
pdf = stats.norm.pdf(x, loc = mean, scale = sd)
# Wrap around the bins
for i in range(1, num_bins):
pdf += stats.norm.pdf(x + i * num_bins, loc = mean, scale = sd)
pdf += stats.norm.pdf(x - i * num_bins, loc = mean, scale = sd)
# Normalize the weights to ensure the sum equals 1
pdf /= pdf.sum()
return pdf
Observations aggregated by season¶
Measurement matrix for monthly-averaged D47 and d18Oc values¶
In [61]:
# Extract measurements and uncertainties from the dictionary
D47_measurements = [measurement["D47_mean"] for measurement in Lutetian_data_monthly_aggregated_dict] # Extract the D47 values from monthly aggregated data
d18Oc_measurements = [measurement["d18O"] for measurement in Lutetian_data_monthly_aggregated_dict] # Extract the d18Oc values from monthly aggregated data
D47_measurements_se = [measurement["D47_SD"] ** 2 for measurement in Lutetian_data_monthly_aggregated_dict] # Square the standard deviation to get the variance
d18Oc_measurements_se = [measurement["d18O_SD"] ** 2 for measurement in Lutetian_data_monthly_aggregated_dict] # Square the standard deviation to get the variance
# OPTIONAL: Lower boundary d18Oc variance at 0.01 (equivalent to 0.1 per mil measurement uncertainty)
d18Oc_measurements_se = [max(uncertainty, 0.01) for uncertainty in d18Oc_measurements_se] # Ensure the uncertainty variance is at least 0.01
# Create the measurement matrix Z
Z = np.array(D47_measurements + d18Oc_measurements).reshape(-1, 1) # Combine D47 and d18Oc measurements into a single matrix
# Create the measurement uncertainty matrix R (diagonal matrix)
R = np.diag(D47_measurements_se + d18Oc_measurements_se) # Combine the variances of D47 and d18Oc measurements into a single diagonal matrix
# Number of seasonally averaged measurements
N_measurements = len(Z) # Get the number of aggregated measurements
Observation matrix for season- and monthly-averaged D47 and d18Oc data from seasonally aggregated proxy measurements¶
In [62]:
# Create the observation matrix H for seasonal data based on seasonally aggregated data
H = np.zeros((N_measurements, len(mu_prior_CESM_4PIC_monthly_combined)))
# Fill the monthly observation matrix H with ones at the positions corresponding to the measurements
half_monthly = int(N_measurements / 2)
for i, measurement in enumerate(Lutetian_data_monthly_aggregated_dict):
month_index = int(measurement["month_score"])
# First half: D47 (SST)
H[i, month_index] = 1
# Second half: d18Oc (SSS)
H[i + half_monthly, month_index + 24] = 1
print(H)
[[1. 0. 0. ... 0. 0. 0.] [0. 1. 0. ... 0. 0. 0.] [0. 0. 1. ... 0. 0. 0.] ... [0. 0. 0. ... 0. 0. 0.] [0. 0. 0. ... 0. 0. 0.] [0. 0. 0. ... 0. 0. 0.]]
DEFINE UPDATING FUNCTIONS¶
Create updating function (Kalman filter)¶
- Include updating of second variable (SAT) through cross-covariance
- Use block updating
Input:
- Prior means (mu_prior)
- Prior covariance matrix (P)
- Observation matrix (H)
- Measurement matrix (Z)
- Uncertainty matrix (R)
Output:
- Posterior means (mu_post)
- Posterior covariance matrix (P_post)
In [63]:
def kalman_update_block(
mu_prior: np.ndarray,
cov_prior: np.ndarray,
Z: np.ndarray,
R: np.ndarray,
H: np.ndarray,
debug_print: bool = False
):
"""
Perform a Kalman update step for a block of observations.
Parameters:
mu_prior (np.ndarray): The prior mean vector.
cov_prior (np.ndarray): The prior covariance matrix.
Z (np.ndarray): The measurement matrix.
R (np.ndarray): The measurement noise covariance matrix.
H (np.ndarray): The observation matrix.
debug_print (bool): If True, print debug statements.
Returns:
mu_posterior (np.ndarray): The posterior mean vector.
cov_posterior (np.ndarray): The posterior covariance matrix.
"""
if debug_print:
# Print shapes of key variables for debugging
print("Shape of cov_prior:", cov_prior.shape)
print("Shape of H:", H.shape)
print("Shape of R:", R.shape)
print("Shape of mu_prior:", mu_prior.shape)
print("Shape of Z:", Z.shape)
# Compute the Kalman gain
K = cov_prior @ H.T @ np.linalg.inv(H @ cov_prior @ H.T + R)
if debug_print:
print("K matrix:", K)
print("Shape of K:", K.shape)
# In-between steps for debugging
Y_hat = H @ mu_prior # Compute the predicted observation
if debug_print:
print("Y_hat:", Y_hat)
print("Shape of Y_hat:", Y_hat.shape)
innovation = Z - Y_hat.reshape(-1, 1) # Compute the innovation
if debug_print:
print("Innovation:", innovation)
print("Shape of innovation:", innovation.shape)
# Replace NaN values in innovation with zeros
innovation = np.nan_to_num(innovation, nan=0.0)
kalman_gain = (K @ innovation).flatten()
if debug_print:
print("Kalman gain:", kalman_gain)
print("Shape of kalman_gain:", kalman_gain.shape)
# Update the posterior mean estimate
mu_posterior = mu_prior + kalman_gain.flatten()
# Update the posterior covariance estimate
cov_posterior = cov_prior - K @ H @ cov_prior
return mu_posterior, cov_posterior
Create function to track the statistics of the likelihood (combining just the reconstruction data)¶
In [64]:
# UPDATED SCRIPT TO ACCOMMODATE MULTIPLE VARIABLES
# Create function to keep track of the likelihood statistics and data
def likelihood_statistics_multi(
weighted_sum,
effective_weights_total,
n_update,
data_library,
measurement,
timestamp,
timestamp_sd,
Variable_names = ["Variable_name1", "Variable_name2"],
Variable_names_SDs = ["Variable_name_SD1", "Variable_name_SD2"]
):
"""
Incrementally updates the likelihood statistics for seasonal data.
Parameters:
- weighted_sum: list
List tracking the mean times the effective weight for each time bin and variable.
- effective_weights_total: list
List tracking the sum of effective weights for each time bin and variable.
- n_update: list
List tracking the number of datapoints for each time bin and variable.
- data_library: dict
Dictionary tracking individual data points and their uncertainties.
- measurement: dict
A single measurement containing data on multiple variables.
- timestamp: str
Key in the measurement dictionary for the timestamp (0-based index).
- timestamp_sd: float
Standard deviation of uncertainty in the timestamp.
- Variable_name: list of str
Key in the measurement dictionary for the variables (e.g. d18Os, D47).
- Variable_name_SD: list of str
Key in the measurement dictionary for the standard deviation on the variables (e.g. d18Os, D47).
"""
# Check if at least one combination of variable name and its SD is present in the measurement
found = False
for var_name, var_sd_name in zip(Variable_names, Variable_names_SDs):
if var_name in measurement and var_sd_name in measurement:
found = True
break
if timestamp in measurement and found:
# Extract the time and data values from the measurement
time = measurement[timestamp]
time_sd = measurement[timestamp_sd]
# Loop through all variable/SD pairs
for var_name, var_sd_name in zip(Variable_names, Variable_names_SDs):
if var_name in measurement and var_sd_name in measurement:
data_val = measurement[var_name]
data_sd = measurement[var_sd_name]
# Check if the data is valid
if not np.isnan(data_val) and not np.isnan(data_sd):
# Calculate the weight (inverse of variance)
weight = 1 / (data_sd ** 2)
# Determine the number of bins
num_bins_seasonal = int(len(weighted_sum) / len(Variable_names))
# Ensure num_bins_seasonal is an integer
bin_indices = np.arange(num_bins_seasonal, dtype=np.float64)
# Calculate the probability density for each bin
if time_sd == 0: # Catch cases where the time uncertainty is zero (or unknown)
probabilities = np.zeros(num_bins_seasonal, dtype=np.float64)
bin_index = int(time) % num_bins_seasonal # Ensure the bin index is within range
probabilities[bin_index] = 1 # Set the probability to 1 for the correct bin
else:
probabilities = stats.norm.pdf(bin_indices, loc=time, scale=time_sd) # For non-zero time uncertainty, use a normal distribution
probabilities /= probabilities.sum() # Normalize to ensure the sum of probabilities is 1
for i, prob in enumerate(probabilities): # Loop over all possible bin numbers in the probability vector
bin_index = i % num_bins_seasonal # Wrap around to the first bin if it overflows
# Update the weighted sums and sample count
effective_weight = weight * prob
var_idx = Variable_names.index(var_name) # Find the index of the variable
idx = int(var_idx * num_bins_seasonal + bin_index) # Unique index for (variable, bin)
if weighted_sum[idx] is None:
weighted_sum[idx] = 0
effective_weights_total[idx] = 0
weighted_sum[idx] = weighted_sum[idx] + data_val * effective_weight
effective_weights_total[idx] = effective_weights_total[idx] + effective_weight
# Update n_update for the correct variable and bin
var_idx = Variable_names.index(var_name) # Find the index of the variable
n_update[var_idx * num_bins_seasonal + (int(time) % num_bins_seasonal)] += 1 # update sample number per bin and variable
# Track individual data points and their uncertainties
key = (var_name, int(time)) # Store individual data points in a dictionary with (variable, time) as key
if key not in data_library:
data_library[key] = [] # Initialize the list for a new (time, var_name) pair
data_library[key].append((time_sd, data_val, data_sd))
return weighted_sum, effective_weights_total, n_update, data_library # Return the updated values
EXECUTE UPDATING FUNCTIONS - MONTHLY¶
Update monthly priors from CESM 4x preindustrial pCO2 with aggregated data¶
- Data and model outcomes aggregated in 12 months
- No sclero-dating uncertainty
- D47 Data aggregated per specimen and per month
In [65]:
# Apply Kalman function to update the prior with monthly data including updating the prec estimates
# Update the monthly D47 and prec prior with all measurements using block updating
monthly_aggregated_data = {} # Keep track of datapoints per season
n_update_CESM_4PIC = np.concatenate([mu_prior_CESM_4PIC_SST_D47_monthly * 0, mu_prior_CESM_4PIC_d18Oc_monthly * 0]) # Vector to store sample size per season for confidence interval plotting
weighted_sum_CESM_4PIC = np.concatenate([mu_prior_CESM_4PIC_SST_D47_monthly * 0, mu_prior_CESM_4PIC_d18Oc_monthly * 0]) # Vector to store mean temperature per season for confidence interval plotting
effective_weights_total_CESM_4PIC = np.concatenate([mu_prior_CESM_4PIC_SST_D47_monthly * 0, mu_prior_CESM_4PIC_d18Oc_monthly * 0]) # Vector to store temperature uncertainty per season for confidence interval plotting
mu_likelihood = np.concatenate([mu_prior_CESM_4PIC_SST_D47_monthly * 0, mu_prior_CESM_4PIC_d18Oc_monthly * 0]) # Vector to store mean temperature per season for confidence interval plotting
std_likelihood = np.concatenate([mu_prior_CESM_4PIC_SST_D47_monthly * 0, mu_prior_CESM_4PIC_d18Oc_monthly * 0]) # Vector to store temperature uncertainty per season for confidence interval plotting
var_names = ["D47_mean", "d18O"] # List of variable names which are updated
var_SD_names = ["D47_SD", "d18O_SD"] # List of names of variable uncertainties which are updated
# Update the prior with monthly data using the Kalman filter in block updating form
mu_post_CESM_4PIC, cov_post_CESM_4PIC = kalman_update_block(
mu_prior_CESM_4PIC_monthly_combined,
cov_prior_CESM_4PIC_monthly_combined,
Z,
R,
H
)
# Extract the updated mean values from the combined state vector
mu_post_CESM_4PIC_SST_D47 = mu_post_CESM_4PIC[:len(mu_prior_CESM_4PIC_SST_D47_monthly)]
mu_post_CESM_4PIC_SAT_D47 = mu_post_CESM_4PIC[len(mu_prior_CESM_4PIC_SST_D47_monthly):2*len(mu_prior_CESM_4PIC_SST_D47_monthly)]
mu_post_CESM_4PIC_d18Oc = mu_post_CESM_4PIC[2*len(mu_prior_CESM_4PIC_SST_D47_monthly):3*len(mu_prior_CESM_4PIC_SST_D47_monthly)]
mu_post_CESM_4PIC_precip = mu_post_CESM_4PIC[3*len(mu_prior_CESM_4PIC_d18Oc_monthly):]
# Extract the updated covariance matrices from the combined covariance matrix
cov_post_CESM_4PIC_SST_D47 = cov_post_CESM_4PIC[:len(mu_prior_CESM_4PIC_SST_D47_monthly), :len(mu_prior_CESM_4PIC_SST_D47_monthly)]
cov_post_CESM_4PIC_SAT_D47 = cov_post_CESM_4PIC[len(mu_prior_CESM_4PIC_SST_D47_monthly):2*len(mu_prior_CESM_4PIC_SST_D47_monthly), len(mu_prior_CESM_4PIC_SST_D47_monthly):2*len(mu_prior_CESM_4PIC_SST_D47_monthly)]
cov_post_CESM_4PIC_d18Oc = cov_post_CESM_4PIC[2*len(mu_prior_CESM_4PIC_SST_D47_monthly):3*len(mu_prior_CESM_4PIC_SST_D47_monthly), 2*len(mu_prior_CESM_4PIC_SST_D47_monthly):3*len(mu_prior_CESM_4PIC_SST_D47_monthly)]
cov_post_CESM_4PIC_precip = cov_post_CESM_4PIC[3*len(mu_prior_CESM_4PIC_d18Oc_monthly):, 3*len(mu_prior_CESM_4PIC_d18Oc_monthly):]
for measurement in Lutetian_data_monthly_aggregated_dict: # Loop over measurements
# Track and update likelihood statistics
weighted_sum_CESM_4PIC, effective_weights_total_CESM_4PIC, n_update_CESM_4PIC, monthly_aggregated_data = likelihood_statistics_multi(
weighted_sum_CESM_4PIC,
effective_weights_total_CESM_4PIC,
n_update_CESM_4PIC,
monthly_aggregated_data,
measurement,
timestamp = "month_score",
timestamp_sd = "Month_err",
Variable_names = var_names,
Variable_names_SDs = var_SD_names
)
# Normalize the weighted_sum_CESM_4PIC to obtain weighted mean
# Calculate inverse square root of the effective_weights_total_CESM_4PIC to contain the weighted standard deviation
# Print likelihood statistics
print("Likelihood statistics:")
num_vars = len(var_names) # number of variables (e.g., D47, d18O)
num_bins_monthly = int(len(weighted_sum_CESM_4PIC) / num_vars)
for var_idx, var_name in enumerate(var_names):
print(f"Results for variable: {var_name}")
for bin_idx in range(num_bins_monthly):
idx = var_idx * num_bins_monthly + bin_idx
if effective_weights_total_CESM_4PIC[idx] is not None and effective_weights_total_CESM_4PIC[idx] != 0:
mu_likelihood[idx] = weighted_sum_CESM_4PIC[idx] / effective_weights_total_CESM_4PIC[idx]
std_likelihood[idx] = np.sqrt(1 / effective_weights_total_CESM_4PIC[idx])
else:
# If there are no data points for this bin, set the likelihood to NaN
mu_likelihood[idx] = np.nan
std_likelihood[idx] = np.nan
print(f" Bin {bin_idx + 1}:")
print(f" Weighted Average: {mu_likelihood[idx]}")
print(f" Aggregated Uncertainty: {std_likelihood[idx]}")
print(f" Number of Data Points: {n_update_CESM_4PIC[idx]}")
print()
print("Original Prior Mean SST-D47 monthly:\n", mu_prior_CESM_4PIC_SST_D47_monthly_original)
print("Original Prior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_prior_CESM_4PIC_SST_D47_monthly_original)))
print("Updated Posterior Mean SST-D47 monthly:\n", mu_post_CESM_4PIC_SST_D47)
print("Updated Posterior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_post_CESM_4PIC_SST_D47)))
print("Original Prior Mean SAT-D47 monthly:\n", mu_prior_CESM_4PIC_SAT_monthly_original)
print("Original Prior Standard Deviation SAT-D47 monthly:\n", np.sqrt(np.diag(cov_prior_CESM_4PIC_SAT_monthly_original)))
print("Updated Posterior Mean SAT-D47 monthly:\n", mu_post_CESM_4PIC_SAT_D47)
print("Updated Posterior Standard Deviation SAT-D47 monthly:\n", np.sqrt(np.diag(cov_post_CESM_4PIC_SAT_D47)))
print("Original Prior Mean d18Oc monthly:\n", mu_prior_CESM_4PIC_d18Oc_monthly_original)
print("Original Prior Standard Deviation d18Oc monthly:\n", np.sqrt(np.diag(cov_prior_CESM_4PIC_d18Oc_monthly_original)))
print("Updated Posterior Mean d18Oc monthly:\n", mu_post_CESM_4PIC_d18Oc)
print("Updated Posterior Standard Deviation d18Oc monthly:\n", np.sqrt(np.diag(cov_post_CESM_4PIC_d18Oc)))
print("Original Prior Mean precipitation monthly:\n", mu_prior_CESM_4PIC_precip_monthly_original)
print("Original Prior Standard Deviation precipitation monthly:\n", np.sqrt(np.diag(cov_prior_CESM_4PIC_precip_monthly_original)))
print("Updated Posterior Mean precipitation monthly:\n", mu_post_CESM_4PIC_precip)
print("Updated Posterior Standard Deviation precipitation monthly:\n", np.sqrt(np.diag(cov_post_CESM_4PIC_precip)))
Likelihood statistics:
Results for variable: D47_mean
Bin 1:
Weighted Average: 0.6315000000000001
Aggregated Uncertainty: 0.0145
Number of Data Points: 1.0
Bin 2:
Weighted Average: 0.5964285714285714
Aggregated Uncertainty: 0.01096096971726759
Number of Data Points: 1.0
Bin 3:
Weighted Average: 0.6065
Aggregated Uncertainty: 0.010253048327204941
Number of Data Points: 1.0
Bin 4:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 5:
Weighted Average: 0.5749687499999999
Aggregated Uncertainty: 0.0051265241636024705
Number of Data Points: 1.0
Bin 6:
Weighted Average: 0.5925625
Aggregated Uncertainty: 0.00725
Number of Data Points: 1.0
Bin 7:
Weighted Average: 0.5888260869565218
Aggregated Uncertainty: 0.004275816728492018
Number of Data Points: 1.0
Bin 8:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 9:
Weighted Average: 0.5830000000000001
Aggregated Uncertainty: 0.004973458969132757
Number of Data Points: 1.0
Bin 10:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 11:
Weighted Average: 0.594
Aggregated Uncertainty: 0.011839200423452026
Number of Data Points: 1.0
Bin 12:
Weighted Average: 0.5921333333333333
Aggregated Uncertainty: 0.007487767802667672
Number of Data Points: 1.0
Results for variable: d18O
Bin 1:
Weighted Average: 0.016000000000000014
Aggregated Uncertainty: 0.0447213595499958
Number of Data Points: 1.0
Bin 2:
Weighted Average: 0.10700000000000001
Aggregated Uncertainty: 0.0316227766016838
Number of Data Points: 1.0
Bin 3:
Weighted Average: -0.22615384615384615
Aggregated Uncertainty: 0.02773500981126146
Number of Data Points: 1.0
Bin 4:
Weighted Average: -0.5469999999999999
Aggregated Uncertainty: 0.01414213562373095
Number of Data Points: 1.0
Bin 5:
Weighted Average: -1.2017647058823526
Aggregated Uncertainty: 0.009166984970282115
Number of Data Points: 1.0
Bin 6:
Weighted Average: -1.6498290598290601
Aggregated Uncertainty: 0.009245003270420488
Number of Data Points: 1.0
Bin 7:
Weighted Average: -2.0610810810810816
Aggregated Uncertainty: 0.009491579957524992
Number of Data Points: 1.0
Bin 8:
Weighted Average: -1.7621904761904763
Aggregated Uncertainty: 0.009759000729485335
Number of Data Points: 1.0
Bin 9:
Weighted Average: -1.3562711864406782
Aggregated Uncertainty: 0.009205746178983237
Number of Data Points: 1.0
Bin 10:
Weighted Average: -0.5620833333333334
Aggregated Uncertainty: 0.014433756729740647
Number of Data Points: 1.0
Bin 11:
Weighted Average: -0.06419354838709676
Aggregated Uncertainty: 0.017960530202677495
Number of Data Points: 1.0
Bin 12:
Weighted Average: -0.162
Aggregated Uncertainty: 0.0223606797749979
Number of Data Points: 1.0
Original Prior Mean SST-D47 monthly:
[0.59656789 0.59858139 0.59867924 0.59638204 0.58858685 0.57705811
0.56727922 0.56351195 0.5670409 0.57510508 0.58376364 0.59171077]
Original Prior Standard Deviation SST-D47 monthly:
[0.00890411 0.00944467 0.00936157 0.00859554 0.00739686 0.00653869
0.00575527 0.00534817 0.00493985 0.00482531 0.00621776 0.00782822]
Updated Posterior Mean SST-D47 monthly:
[0.59746433 0.59942274 0.59953844 0.59638204 0.5892276 0.57770401
0.56711071 0.56351195 0.56748139 0.57510508 0.58307085 0.5924027 ]
Updated Posterior Standard Deviation SST-D47 monthly:
[1.32467442e-03 8.57442039e-04 5.08756743e-04 7.08126758e-10
9.15449230e-04 8.96916623e-04 3.84829259e-04 5.20625146e-10
7.72355884e-04 1.02815228e-09 1.25655914e-03 1.58388923e-03]
Original Prior Mean SAT-D47 monthly:
[16.27954224 17.01156006 18.66868896 21.54889648 27.12244995 32.0811853
35.76927734 35.78623779 32.02878784 25.72896606 20.42561768 17.17369751]
Original Prior Standard Deviation SAT-D47 monthly:
[3.46377896 3.10594374 2.78918732 2.54271169 2.46488387 2.73331005
2.85535749 2.646315 2.52596201 3.00791784 3.58824735 3.69933077]
Updated Posterior Mean SAT-D47 monthly:
[0.58384115 0.57819316 0.57212356 0.56538091 0.55283988 0.5417955
0.5352128 0.53646114 0.54908711 0.56900319 0.58019837 0.58547234]
Updated Posterior Standard Deviation SAT-D47 monthly:
[0.00205032 0.00212821 0.00216467 0.00213557 0.00197392 0.00179966
0.00174475 0.00179853 0.0016947 0.00147584 0.00164494 0.00189799]
Original Prior Mean d18Oc monthly:
[-0.87134431 -0.71613404 -0.7139883 -0.89894578 -1.51047705 -2.43504627
-3.25136303 -3.57317763 -3.27234184 -2.5945588 -1.88634864 -1.25084057]
Original Prior Standard Deviation d18Oc monthly:
[0.43074162 0.4079074 0.39792762 0.39889866 0.41067086 0.41700845
0.43048772 0.48872905 0.56171093 0.58936283 0.51749387 0.46825537]
Updated Posterior Mean d18Oc monthly:
[-0.0594466 -0.16160171 -0.22093518 -0.23611568 -0.55835238 -1.31067957
-1.89449543 -2.11835829 -1.58325457 -0.69231214 -0.34526637 -0.09119921]
Updated Posterior Standard Deviation d18Oc monthly:
[0.03807578 0.03552346 0.03066903 0.02830315 0.02933908 0.03518046
0.04691073 0.04543986 0.04263553 0.05642311 0.04493518 0.03952293]
Original Prior Mean precipitation monthly:
[2.05036495 2.09002108 2.13109892 1.96715635 1.40643449 1.6901619
2.09515585 1.98018534 1.94212635 1.63982346 1.82765013 1.94334188]
Original Prior Standard Deviation precipitation monthly:
[0.66564033 0.62619878 0.56043175 0.67673041 0.71392551 0.98128657
1.25333983 1.00710893 0.75627296 0.48859499 0.68684095 0.68028201]
Updated Posterior Mean precipitation monthly:
[1.05596221 1.25717489 1.73422117 2.1719024 1.62552508 1.90734963
2.44764801 2.1186652 2.1632807 2.20086806 1.51119957 1.26216664]
Updated Posterior Standard Deviation precipitation monthly:
[0.44758034 0.43024669 0.32290945 0.30670749 0.22057566 0.31346525
0.41539167 0.4164468 0.5090759 0.38526466 0.29114281 0.29528475]
Update monthly priors from CESM 2x preindustrial pCO2 with aggregated data¶
- Data and model outcomes aggregated in 12 months
- No sclero-dating uncertainty
- D47 Data aggregated per specimen and per month
In [66]:
# Apply Kalman function to update the prior with monthly data including updating the prec estimates
# Update the monthly D47 and prec prior with all measurements using block updating
monthly_aggregated_data = {} # Keep track of datapoints per season
n_update_CESM_2PIC = np.concatenate([mu_prior_CESM_2PIC_SST_D47_monthly * 0, mu_prior_CESM_2PIC_d18Oc_monthly * 0]) # Vector to store sample size per season for confidence interval plotting
weighted_sum_CESM_2PIC = np.concatenate([mu_prior_CESM_2PIC_SST_D47_monthly * 0, mu_prior_CESM_2PIC_d18Oc_monthly * 0]) # Vector to store mean temperature per season for confidence interval plotting
effective_weights_total_CESM_2PIC = np.concatenate([mu_prior_CESM_2PIC_SST_D47_monthly * 0, mu_prior_CESM_2PIC_d18Oc_monthly * 0]) # Vector to store temperature uncertainty per season for confidence interval plotting
mu_likelihood = np.concatenate([mu_prior_CESM_2PIC_SST_D47_monthly * 0, mu_prior_CESM_2PIC_d18Oc_monthly * 0]) # Vector to store mean temperature per season for confidence interval plotting
std_likelihood = np.concatenate([mu_prior_CESM_2PIC_SST_D47_monthly * 0, mu_prior_CESM_2PIC_d18Oc_monthly * 0]) # Vector to store temperature uncertainty per season for confidence interval plotting
var_names = ["D47_mean", "d18O"] # List of variable names which are updated
var_SD_names = ["D47_SD", "d18O_SD"] # List of names of variable uncertainties which are updated
# Update the prior with monthly data using the Kalman filter in block updating form
mu_post_CESM_2PIC, cov_post_CESM_2PIC = kalman_update_block(
mu_prior_CESM_2PIC_monthly_combined,
cov_prior_CESM_2PIC_monthly_combined,
Z,
R,
H
)
# Extract the updated mean values from the combined state vector
mu_post_CESM_2PIC_SST_D47 = mu_post_CESM_2PIC[:len(mu_prior_CESM_2PIC_SST_D47_monthly)]
mu_post_CESM_2PIC_SAT_D47 = mu_post_CESM_2PIC[len(mu_prior_CESM_2PIC_SST_D47_monthly):2*len(mu_prior_CESM_2PIC_SST_D47_monthly)]
mu_post_CESM_2PIC_d18Oc = mu_post_CESM_2PIC[2*len(mu_prior_CESM_2PIC_SST_D47_monthly):3*len(mu_prior_CESM_2PIC_SST_D47_monthly)]
mu_post_CESM_2PIC_precip = mu_post_CESM_2PIC[3*len(mu_prior_CESM_2PIC_d18Oc_monthly):]
# Extract the updated covariance matrices from the combined covariance matrix
cov_post_CESM_2PIC_SST_D47 = cov_post_CESM_2PIC[:len(mu_prior_CESM_2PIC_SST_D47_monthly), :len(mu_prior_CESM_2PIC_SST_D47_monthly)]
cov_post_CESM_2PIC_SAT_D47 = cov_post_CESM_2PIC[len(mu_prior_CESM_2PIC_SST_D47_monthly):2*len(mu_prior_CESM_2PIC_SST_D47_monthly), len(mu_prior_CESM_2PIC_SST_D47_monthly):2*len(mu_prior_CESM_2PIC_SST_D47_monthly)]
cov_post_CESM_2PIC_d18Oc = cov_post_CESM_2PIC[2*len(mu_prior_CESM_2PIC_SST_D47_monthly):3*len(mu_prior_CESM_2PIC_SST_D47_monthly), 2*len(mu_prior_CESM_2PIC_SST_D47_monthly):3*len(mu_prior_CESM_2PIC_SST_D47_monthly)]
cov_post_CESM_2PIC_precip = cov_post_CESM_2PIC[3*len(mu_prior_CESM_2PIC_d18Oc_monthly):, 3*len(mu_prior_CESM_2PIC_d18Oc_monthly):]
for measurement in Lutetian_data_monthly_aggregated_dict: # Loop over measurements
# Track and update likelihood statistics
weighted_sum_CESM_2PIC, effective_weights_total_CESM_2PIC, n_update_CESM_2PIC, monthly_aggregated_data = likelihood_statistics_multi(
weighted_sum_CESM_2PIC,
effective_weights_total_CESM_2PIC,
n_update_CESM_2PIC,
monthly_aggregated_data,
measurement,
timestamp = "month_score",
timestamp_sd = "Month_err",
Variable_names = var_names,
Variable_names_SDs = var_SD_names
)
# Normalize the weighted_sum_CESM_2PIC to obtain weighted mean
# Calculate inverse square root of the effective_weights_total_CESM_2PIC to contain the weighted standard deviation
# Print likelihood statistics
print("Likelihood statistics:")
num_vars = len(var_names) # number of variables (e.g., D47, d18O)
num_bins_monthly = int(len(weighted_sum_CESM_2PIC) / num_vars)
for var_idx, var_name in enumerate(var_names):
print(f"Results for variable: {var_name}")
for bin_idx in range(num_bins_monthly):
idx = var_idx * num_bins_monthly + bin_idx
if effective_weights_total_CESM_2PIC[idx] is not None and effective_weights_total_CESM_2PIC[idx] != 0:
mu_likelihood[idx] = weighted_sum_CESM_2PIC[idx] / effective_weights_total_CESM_2PIC[idx]
std_likelihood[idx] = np.sqrt(1 / effective_weights_total_CESM_2PIC[idx])
else:
# If there are no data points for this bin, set the likelihood to NaN
mu_likelihood[idx] = np.nan
std_likelihood[idx] = np.nan
print(f" Bin {bin_idx + 1}:")
print(f" Weighted Average: {mu_likelihood[idx]}")
print(f" Aggregated Uncertainty: {std_likelihood[idx]}")
print(f" Number of Data Points: {n_update_CESM_2PIC[idx]}")
print()
print("Original Prior Mean SST-D47 monthly:\n", mu_prior_CESM_2PIC_SST_D47_monthly_original)
print("Original Prior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_prior_CESM_2PIC_SST_D47_monthly_original)))
print("Updated Posterior Mean SST-D47 monthly:\n", mu_post_CESM_2PIC_SST_D47)
print("Updated Posterior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_post_CESM_2PIC_SST_D47)))
print("Original Prior Mean SAT-D47 monthly:\n", mu_prior_CESM_2PIC_SAT_monthly_original)
print("Original Prior Standard Deviation SAT-D47 monthly:\n", np.sqrt(np.diag(cov_prior_CESM_2PIC_SAT_monthly_original)))
print("Updated Posterior Mean SAT-D47 monthly:\n", mu_post_CESM_2PIC_SAT_D47)
print("Updated Posterior Standard Deviation SAT-D47 monthly:\n", np.sqrt(np.diag(cov_post_CESM_2PIC_SAT_D47)))
print("Original Prior Mean d18Oc monthly:\n", mu_prior_CESM_2PIC_d18Oc_monthly_original)
print("Original Prior Standard Deviation d18Oc monthly:\n", np.sqrt(np.diag(cov_prior_CESM_2PIC_d18Oc_monthly_original)))
print("Updated Posterior Mean d18Oc monthly:\n", mu_post_CESM_2PIC_d18Oc)
print("Updated Posterior Standard Deviation d18Oc monthly:\n", np.sqrt(np.diag(cov_post_CESM_2PIC_d18Oc)))
print("Original Prior Mean precipitation monthly:\n", mu_prior_CESM_2PIC_precip_monthly_original)
print("Original Prior Standard Deviation precipitation monthly:\n", np.sqrt(np.diag(cov_prior_CESM_2PIC_precip_monthly_original)))
print("Updated Posterior Mean precipitation monthly:\n", mu_post_CESM_2PIC_precip)
print("Updated Posterior Standard Deviation precipitation monthly:\n", np.sqrt(np.diag(cov_post_CESM_2PIC_precip)))
Likelihood statistics:
Results for variable: D47_mean
Bin 1:
Weighted Average: 0.6315000000000001
Aggregated Uncertainty: 0.0145
Number of Data Points: 1.0
Bin 2:
Weighted Average: 0.5964285714285714
Aggregated Uncertainty: 0.01096096971726759
Number of Data Points: 1.0
Bin 3:
Weighted Average: 0.6065
Aggregated Uncertainty: 0.010253048327204941
Number of Data Points: 1.0
Bin 4:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 5:
Weighted Average: 0.5749687499999999
Aggregated Uncertainty: 0.0051265241636024705
Number of Data Points: 1.0
Bin 6:
Weighted Average: 0.5925625
Aggregated Uncertainty: 0.00725
Number of Data Points: 1.0
Bin 7:
Weighted Average: 0.5888260869565218
Aggregated Uncertainty: 0.004275816728492018
Number of Data Points: 1.0
Bin 8:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 9:
Weighted Average: 0.5830000000000001
Aggregated Uncertainty: 0.004973458969132757
Number of Data Points: 1.0
Bin 10:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 11:
Weighted Average: 0.594
Aggregated Uncertainty: 0.011839200423452026
Number of Data Points: 1.0
Bin 12:
Weighted Average: 0.5921333333333333
Aggregated Uncertainty: 0.007487767802667672
Number of Data Points: 1.0
Results for variable: d18O
Bin 1:
Weighted Average: 0.016000000000000014
Aggregated Uncertainty: 0.0447213595499958
Number of Data Points: 1.0
Bin 2:
Weighted Average: 0.10700000000000001
Aggregated Uncertainty: 0.0316227766016838
Number of Data Points: 1.0
Bin 3:
Weighted Average: -0.22615384615384615
Aggregated Uncertainty: 0.02773500981126146
Number of Data Points: 1.0
Bin 4:
Weighted Average: -0.5469999999999999
Aggregated Uncertainty: 0.01414213562373095
Number of Data Points: 1.0
Bin 5:
Weighted Average: -1.2017647058823526
Aggregated Uncertainty: 0.009166984970282115
Number of Data Points: 1.0
Bin 6:
Weighted Average: -1.6498290598290601
Aggregated Uncertainty: 0.009245003270420488
Number of Data Points: 1.0
Bin 7:
Weighted Average: -2.0610810810810816
Aggregated Uncertainty: 0.009491579957524992
Number of Data Points: 1.0
Bin 8:
Weighted Average: -1.7621904761904763
Aggregated Uncertainty: 0.009759000729485335
Number of Data Points: 1.0
Bin 9:
Weighted Average: -1.3562711864406782
Aggregated Uncertainty: 0.009205746178983237
Number of Data Points: 1.0
Bin 10:
Weighted Average: -0.5620833333333334
Aggregated Uncertainty: 0.014433756729740647
Number of Data Points: 1.0
Bin 11:
Weighted Average: -0.06419354838709676
Aggregated Uncertainty: 0.017960530202677495
Number of Data Points: 1.0
Bin 12:
Weighted Average: -0.162
Aggregated Uncertainty: 0.0223606797749979
Number of Data Points: 1.0
Original Prior Mean SST-D47 monthly:
[0.60489442 0.60666426 0.60683094 0.60417118 0.59618643 0.58512465
0.5755485 0.57189757 0.57548974 0.58366672 0.59236182 0.60038379]
Original Prior Standard Deviation SST-D47 monthly:
[0.01009378 0.01057793 0.01042161 0.00955301 0.00826056 0.00738042
0.0066458 0.00598658 0.00544544 0.0055813 0.00709986 0.00884544]
Updated Posterior Mean SST-D47 monthly:
[0.60633943 0.60835679 0.60830884 0.60417118 0.59553875 0.58497423
0.5756302 0.57189757 0.57513078 0.58366672 0.59201352 0.60122747]
Updated Posterior Standard Deviation SST-D47 monthly:
[1.13760750e-03 7.29759587e-04 5.00967118e-04 9.38570330e-10
6.43713775e-04 6.60290236e-04 6.33168776e-04 5.82076609e-10
6.31370286e-04 1.16415322e-10 1.13779597e-03 1.42740787e-03]
Original Prior Mean SAT-D47 monthly:
[13.07259888 13.64740356 15.16016968 18.37324585 23.23636963 27.22269897
30.5027002 30.95843628 27.72623169 21.72160767 16.61921631 13.56875732]
Original Prior Standard Deviation SAT-D47 monthly:
[3.54443863 3.25051999 2.97972364 2.6082818 2.44318742 2.633592
2.9258649 2.76327261 2.72785837 3.26765855 3.74834864 3.87666334]
Updated Posterior Mean SAT-D47 monthly:
[0.59641559 0.59232005 0.58723814 0.57894764 0.56739206 0.55832183
0.55059838 0.55139891 0.56379469 0.58269717 0.59403101 0.5989389 ]
Updated Posterior Standard Deviation SAT-D47 monthly:
[0.00238229 0.00246252 0.00250725 0.00247176 0.0022723 0.00210167
0.00205337 0.0020195 0.00188792 0.00176289 0.00193812 0.00218669]
Original Prior Mean d18Oc monthly:
[-0.20804548 -0.07873241 -0.07509482 -0.29063799 -0.90690032 -1.77413891
-2.55085312 -2.84797432 -2.54024627 -1.8689654 -1.17633926 -0.55155968]
Original Prior Standard Deviation d18Oc monthly:
[0.40225003 0.393072 0.38290499 0.36843204 0.36587289 0.37604721
0.38016149 0.44783066 0.51482087 0.52320248 0.45863081 0.42027637]
Updated Posterior Mean d18Oc monthly:
[-0.09222312 -0.13436748 -0.14611606 -0.20941588 -0.58108839 -1.28830361
-1.97993509 -2.11259651 -1.48770687 -0.66398609 -0.31352031 -0.09363682]
Updated Posterior Standard Deviation d18Oc monthly:
[0.04168471 0.03755797 0.03383831 0.03032566 0.02914058 0.03505934
0.04651381 0.04561031 0.04852235 0.05893546 0.04279788 0.04020513]
Original Prior Mean precipitation monthly:
[2.02240836 2.1888688 2.37645928 2.1330658 1.70077639 1.93969147
2.35826096 2.03186492 1.81291405 1.57573304 2.40556723 2.22682322]
Original Prior Standard Deviation precipitation monthly:
[0.71949004 0.82266634 0.74623178 0.7373264 0.8970992 1.16473376
1.52905146 1.05236599 0.73902296 0.47685306 0.73744784 0.91193706]
Updated Posterior Mean precipitation monthly:
[0.57809946 0.38905027 0.72943062 1.64125147 1.68506424 0.82097809
2.01316514 1.74573788 1.30044782 1.65315879 1.38000985 1.49769403]
Updated Posterior Standard Deviation precipitation monthly:
[0.51920344 0.61375606 0.53010315 0.34515565 0.2069392 0.47345971
0.5604462 0.52280179 0.54586465 0.32693473 0.42293934 0.4186884 ]
Update monthly priors from HadCM (new) 1x preindustrial pCO2 with aggregated data¶
- Data and model outcomes aggregated in 12 months
- No sclero-dating uncertainty
- D47 Data aggregated per specimen and per month
In [67]:
# Apply Kalman function to update the prior with monthly data including updating the prec estimates
# Update the monthly D47 and prec prior with all measurements using block updating
monthly_aggregated_data = {} # Keep track of datapoints per season
n_update_HadCM_new_1PIC = np.concatenate([mu_prior_HadCM_new_1PIC_SST_D47_monthly * 0, mu_prior_HadCM_new_1PIC_d18Oc_monthly * 0]) # Vector to store sample size per season for confidence interval plotting
weighted_sum_HadCM_new_1PIC = np.concatenate([mu_prior_HadCM_new_1PIC_SST_D47_monthly * 0, mu_prior_HadCM_new_1PIC_d18Oc_monthly * 0]) # Vector to store mean temperature per season for confidence interval plotting
effective_weights_total_HadCM_new_1PIC = np.concatenate([mu_prior_HadCM_new_1PIC_SST_D47_monthly * 0, mu_prior_HadCM_new_1PIC_d18Oc_monthly * 0]) # Vector to store temperature uncertainty per season for confidence interval plotting
mu_likelihood = np.concatenate([mu_prior_HadCM_new_1PIC_SST_D47_monthly * 0, mu_prior_HadCM_new_1PIC_d18Oc_monthly * 0]) # Vector to store mean temperature per season for confidence interval plotting
std_likelihood = np.concatenate([mu_prior_HadCM_new_1PIC_SST_D47_monthly * 0, mu_prior_HadCM_new_1PIC_d18Oc_monthly * 0]) # Vector to store temperature uncertainty per season for confidence interval plotting
var_names = ["D47_mean", "d18O"] # List of variable names which are updated
var_SD_names = ["D47_SD", "d18O_SD"] # List of names of variable uncertainties which are updated
# Update the prior with monthly data using the Kalman filter in block updating form
mu_post_HadCM_new_1PIC, cov_post_HadCM_new_1PIC = kalman_update_block(
mu_prior_HadCM_new_1PIC_monthly_combined,
cov_prior_HadCM_new_1PIC_monthly_combined,
Z,
R,
H
)
# Extract the updated mean values from the combined state vector
mu_post_HadCM_new_1PIC_SST_D47 = mu_post_HadCM_new_1PIC[:len(mu_prior_HadCM_new_1PIC_SST_D47_monthly)]
mu_post_HadCM_new_1PIC_SAT_D47 = mu_post_HadCM_new_1PIC[len(mu_prior_HadCM_new_1PIC_SST_D47_monthly):2*len(mu_prior_HadCM_new_1PIC_SST_D47_monthly)]
mu_post_HadCM_new_1PIC_d18Oc = mu_post_HadCM_new_1PIC[2*len(mu_prior_HadCM_new_1PIC_SST_D47_monthly):3*len(mu_prior_HadCM_new_1PIC_SST_D47_monthly)]
mu_post_HadCM_new_1PIC_precip = mu_post_HadCM_new_1PIC[3*len(mu_prior_HadCM_new_1PIC_d18Oc_monthly):]
# Extract the updated covariance matrices from the combined covariance matrix
cov_post_HadCM_new_1PIC_SST_D47 = cov_post_HadCM_new_1PIC[:len(mu_prior_HadCM_new_1PIC_SST_D47_monthly), :len(mu_prior_HadCM_new_1PIC_SST_D47_monthly)]
cov_post_HadCM_new_1PIC_SAT_D47 = cov_post_HadCM_new_1PIC[len(mu_prior_HadCM_new_1PIC_SST_D47_monthly):2*len(mu_prior_HadCM_new_1PIC_SST_D47_monthly), len(mu_prior_HadCM_new_1PIC_SST_D47_monthly):2*len(mu_prior_HadCM_new_1PIC_SST_D47_monthly)]
cov_post_HadCM_new_1PIC_d18Oc = cov_post_HadCM_new_1PIC[2*len(mu_prior_HadCM_new_1PIC_SST_D47_monthly):3*len(mu_prior_HadCM_new_1PIC_SST_D47_monthly), 2*len(mu_prior_HadCM_new_1PIC_SST_D47_monthly):3*len(mu_prior_HadCM_new_1PIC_SST_D47_monthly)]
cov_post_HadCM_new_1PIC_precip = cov_post_HadCM_new_1PIC[3*len(mu_prior_HadCM_new_1PIC_d18Oc_monthly):, 3*len(mu_prior_HadCM_new_1PIC_d18Oc_monthly):]
for measurement in Lutetian_data_monthly_aggregated_dict: # Loop over measurements
# Track and update likelihood statistics
weighted_sum_HadCM_new_1PIC, effective_weights_total_HadCM_new_1PIC, n_update_HadCM_new_1PIC, monthly_aggregated_data = likelihood_statistics_multi(
weighted_sum_HadCM_new_1PIC,
effective_weights_total_HadCM_new_1PIC,
n_update_HadCM_new_1PIC,
monthly_aggregated_data,
measurement,
timestamp = "month_score",
timestamp_sd = "Month_err",
Variable_names = var_names,
Variable_names_SDs = var_SD_names
)
# Normalize the weighted_sum_HadCM_new_1PIC to obtain weighted mean
# Calculate inverse square root of the effective_weights_total_HadCM_new_1PIC to contain the weighted standard deviation
# Print likelihood statistics
print("Likelihood statistics:")
num_vars = len(var_names) # number of variables (e.g., D47, d18O)
num_bins_monthly = int(len(weighted_sum_HadCM_new_1PIC) / num_vars)
for var_idx, var_name in enumerate(var_names):
print(f"Results for variable: {var_name}")
for bin_idx in range(num_bins_monthly):
idx = var_idx * num_bins_monthly + bin_idx
if effective_weights_total_HadCM_new_1PIC[idx] is not None and effective_weights_total_HadCM_new_1PIC[idx] != 0:
mu_likelihood[idx] = weighted_sum_HadCM_new_1PIC[idx] / effective_weights_total_HadCM_new_1PIC[idx]
std_likelihood[idx] = np.sqrt(1 / effective_weights_total_HadCM_new_1PIC[idx])
else:
# If there are no data points for this bin, set the likelihood to NaN
mu_likelihood[idx] = np.nan
std_likelihood[idx] = np.nan
print(f" Bin {bin_idx + 1}:")
print(f" Weighted Average: {mu_likelihood[idx]}")
print(f" Aggregated Uncertainty: {std_likelihood[idx]}")
print(f" Number of Data Points: {n_update_HadCM_new_1PIC[idx]}")
print()
print("Original Prior Mean SST-D47 monthly:\n", mu_prior_HadCM_new_1PIC_SST_D47_monthly_original)
print("Original Prior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_new_1PIC_SST_D47_monthly_original)))
print("Updated Posterior Mean SST-D47 monthly:\n", mu_post_HadCM_new_1PIC_SST_D47)
print("Updated Posterior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_post_HadCM_new_1PIC_SST_D47)))
print("Original Prior Mean SAT-D47 monthly:\n", mu_prior_HadCM_new_1PIC_SAT_monthly_original)
print("Original Prior Standard Deviation SAT-D47 monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_new_1PIC_SAT_monthly_original)))
print("Updated Posterior Mean SAT-D47 monthly:\n", mu_post_HadCM_new_1PIC_SAT_D47)
print("Updated Posterior Standard Deviation SAT-D47 monthly:\n", np.sqrt(np.diag(cov_post_HadCM_new_1PIC_SAT_D47)))
print("Original Prior Mean d18Oc monthly:\n", mu_prior_HadCM_new_1PIC_d18Oc_monthly_original)
print("Original Prior Standard Deviation d18Oc monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_new_1PIC_d18Oc_monthly_original)))
print("Updated Posterior Mean d18Oc monthly:\n", mu_post_HadCM_new_1PIC_d18Oc)
print("Updated Posterior Standard Deviation d18Oc monthly:\n", np.sqrt(np.diag(cov_post_HadCM_new_1PIC_d18Oc)))
print("Original Prior Mean precipitation monthly:\n", mu_prior_HadCM_new_1PIC_precip_monthly_original)
print("Original Prior Standard Deviation precipitation monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_new_1PIC_precip_monthly_original)))
print("Updated Posterior Mean precipitation monthly:\n", mu_post_HadCM_new_1PIC_precip)
print("Updated Posterior Standard Deviation precipitation monthly:\n", np.sqrt(np.diag(cov_post_HadCM_new_1PIC_precip)))
Likelihood statistics:
Results for variable: D47_mean
Bin 1:
Weighted Average: 0.6315000000000001
Aggregated Uncertainty: 0.0145
Number of Data Points: 1.0
Bin 2:
Weighted Average: 0.5964285714285714
Aggregated Uncertainty: 0.01096096971726759
Number of Data Points: 1.0
Bin 3:
Weighted Average: 0.6065
Aggregated Uncertainty: 0.010253048327204941
Number of Data Points: 1.0
Bin 4:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 5:
Weighted Average: 0.5749687499999999
Aggregated Uncertainty: 0.0051265241636024705
Number of Data Points: 1.0
Bin 6:
Weighted Average: 0.5925625
Aggregated Uncertainty: 0.00725
Number of Data Points: 1.0
Bin 7:
Weighted Average: 0.5888260869565218
Aggregated Uncertainty: 0.004275816728492018
Number of Data Points: 1.0
Bin 8:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 9:
Weighted Average: 0.5830000000000001
Aggregated Uncertainty: 0.004973458969132757
Number of Data Points: 1.0
Bin 10:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 11:
Weighted Average: 0.594
Aggregated Uncertainty: 0.011839200423452026
Number of Data Points: 1.0
Bin 12:
Weighted Average: 0.5921333333333333
Aggregated Uncertainty: 0.007487767802667672
Number of Data Points: 1.0
Results for variable: d18O
Bin 1:
Weighted Average: 0.016000000000000014
Aggregated Uncertainty: 0.0447213595499958
Number of Data Points: 1.0
Bin 2:
Weighted Average: 0.10700000000000001
Aggregated Uncertainty: 0.0316227766016838
Number of Data Points: 1.0
Bin 3:
Weighted Average: -0.22615384615384615
Aggregated Uncertainty: 0.02773500981126146
Number of Data Points: 1.0
Bin 4:
Weighted Average: -0.5469999999999999
Aggregated Uncertainty: 0.01414213562373095
Number of Data Points: 1.0
Bin 5:
Weighted Average: -1.2017647058823526
Aggregated Uncertainty: 0.009166984970282115
Number of Data Points: 1.0
Bin 6:
Weighted Average: -1.6498290598290601
Aggregated Uncertainty: 0.009245003270420488
Number of Data Points: 1.0
Bin 7:
Weighted Average: -2.0610810810810816
Aggregated Uncertainty: 0.009491579957524992
Number of Data Points: 1.0
Bin 8:
Weighted Average: -1.7621904761904763
Aggregated Uncertainty: 0.009759000729485335
Number of Data Points: 1.0
Bin 9:
Weighted Average: -1.3562711864406782
Aggregated Uncertainty: 0.009205746178983237
Number of Data Points: 1.0
Bin 10:
Weighted Average: -0.5620833333333334
Aggregated Uncertainty: 0.014433756729740647
Number of Data Points: 1.0
Bin 11:
Weighted Average: -0.06419354838709676
Aggregated Uncertainty: 0.017960530202677495
Number of Data Points: 1.0
Bin 12:
Weighted Average: -0.162
Aggregated Uncertainty: 0.0223606797749979
Number of Data Points: 1.0
Original Prior Mean SST-D47 monthly:
[0.62836703 0.63114362 0.6315288 0.62910984 0.62039478 0.60379994
0.59226822 0.58947313 0.5946067 0.60517016 0.61565939 0.62340158]
Original Prior Standard Deviation SST-D47 monthly:
[0.01239925 0.01298432 0.01278486 0.01157278 0.00894292 0.00575495
0.00332249 0.00262989 0.0050293 0.00800725 0.0098363 0.01123015]
Updated Posterior Mean SST-D47 monthly:
[0.6148096 0.62053421 0.625955 0.62910984 0.62665477 0.61089807
0.59512173 0.58947313 0.59479705 0.60517016 0.6125581 0.61409802]
Updated Posterior Standard Deviation SST-D47 monthly:
[7.97462698e-04 7.16214541e-04 4.59243610e-04 1.84436556e-09
5.73810778e-04 6.87700310e-04 2.06448258e-04 4.92190434e-10
1.20030181e-04 1.61729334e-09 1.44899233e-04 4.85196679e-04]
Original Prior Mean SAT-D47 monthly:
[10.08334503 10.0055481 10.76345469 12.26940816 15.83041026 20.84376678
24.38166707 25.21004893 23.2913503 19.00565236 14.61674144 11.84420675]
Original Prior Standard Deviation SAT-D47 monthly:
[3.96689536 3.6677536 3.37467091 2.96255495 2.3892861 1.69618705
1.01561685 0.897383 1.69453479 2.75833427 3.47391248 3.86029272]
Updated Posterior Mean SAT-D47 monthly:
[0.60360563 0.60377625 0.60087487 0.59615204 0.58934856 0.58098627
0.57634057 0.5780185 0.58035622 0.58635895 0.59559924 0.600128 ]
Updated Posterior Standard Deviation SAT-D47 monthly:
[0.00080107 0.0008285 0.0008224 0.0009281 0.00108508 0.00092428
0.00067118 0.00053011 0.0004584 0.00066915 0.00084274 0.00085404]
Original Prior Mean d18Oc monthly:
[ 1.96163182 2.15696186 2.18020776 2.0017259 1.36800588 0.1424221
-0.73896791 -0.96534146 -0.5598614 0.26223308 1.0455347 1.60694956]
Original Prior Standard Deviation d18Oc monthly:
[0.74655093 0.78001576 0.76607827 0.69073309 0.52749869 0.32304877
0.16440636 0.12281718 0.28404232 0.48860193 0.59855519 0.67791903]
Updated Posterior Mean d18Oc monthly:
[-0.06605668 0.09116253 0.0664248 -0.11401332 -0.46110761 -1.25769733
-1.71707111 -1.59985516 -1.42991687 -1.07534712 -0.54037574 -0.25722263]
Updated Posterior Standard Deviation d18Oc monthly:
[0.04584503 0.05021895 0.04482341 0.04222399 0.04981098 0.04682638
0.04662781 0.04847023 0.03337761 0.03412356 0.04354023 0.04498715]
Original Prior Mean precipitation monthly:
[2.93467813 2.51780503 2.36863809 2.23043843 2.39540224 2.0227101
3.48519517 3.86902922 3.50113248 3.86729931 3.88739363 3.5501087 ]
Original Prior Standard Deviation precipitation monthly:
[0.55099183 0.33959534 0.30486469 0.38027225 0.8389547 1.13985648
1.28457778 0.88043538 0.83027462 0.81630782 0.57832729 0.61808957]
Updated Posterior Mean precipitation monthly:
[5.8602765 5.15454372 3.91008794 3.01792761 1.34490261 0.7967566
5.24010718 8.08328405 7.25484027 8.73891028 7.15872439 6.85176391]
Updated Posterior Standard Deviation precipitation monthly:
[0.25263177 0.22162949 0.19905823 0.15814356 0.31922835 0.2508503
0.38713572 0.36478263 0.579605 0.4842891 0.38831833 0.31256322]
Update monthly priors from HadCM (new) 2x preindustrial pCO2 with aggregated data¶
- Data and model outcomes aggregated in 12 months
- No sclero-dating uncertainty
- D47 Data aggregated per specimen and per month
In [68]:
# Apply Kalman function to update the prior with monthly data including updating the prec estimates
# Update the monthly D47 and prec prior with all measurements using block updating
monthly_aggregated_data = {} # Keep track of datapoints per season
n_update_HadCM_new_2PIC = np.concatenate([mu_prior_HadCM_new_2PIC_SST_D47_monthly * 0, mu_prior_HadCM_new_2PIC_d18Oc_monthly * 0]) # Vector to store sample size per season for confidence interval plotting
weighted_sum_HadCM_new_2PIC = np.concatenate([mu_prior_HadCM_new_2PIC_SST_D47_monthly * 0, mu_prior_HadCM_new_2PIC_d18Oc_monthly * 0]) # Vector to store mean temperature per season for confidence interval plotting
effective_weights_total_HadCM_new_2PIC = np.concatenate([mu_prior_HadCM_new_2PIC_SST_D47_monthly * 0, mu_prior_HadCM_new_2PIC_d18Oc_monthly * 0]) # Vector to store temperature uncertainty per season for confidence interval plotting
mu_likelihood = np.concatenate([mu_prior_HadCM_new_2PIC_SST_D47_monthly * 0, mu_prior_HadCM_new_2PIC_d18Oc_monthly * 0]) # Vector to store mean temperature per season for confidence interval plotting
std_likelihood = np.concatenate([mu_prior_HadCM_new_2PIC_SST_D47_monthly * 0, mu_prior_HadCM_new_2PIC_d18Oc_monthly * 0]) # Vector to store temperature uncertainty per season for confidence interval plotting
var_names = ["D47_mean", "d18O"] # List of variable names which are updated
var_SD_names = ["D47_SD", "d18O_SD"] # List of names of variable uncertainties which are updated
# Update the prior with monthly data using the Kalman filter in block updating form
mu_post_HadCM_new_2PIC, cov_post_HadCM_new_2PIC = kalman_update_block(
mu_prior_HadCM_new_2PIC_monthly_combined,
cov_prior_HadCM_new_2PIC_monthly_combined,
Z,
R,
H
)
# Extract the updated mean values from the combined state vector
mu_post_HadCM_new_2PIC_SST_D47 = mu_post_HadCM_new_2PIC[:len(mu_prior_HadCM_new_2PIC_SST_D47_monthly)]
mu_post_HadCM_new_2PIC_SAT_D47 = mu_post_HadCM_new_2PIC[len(mu_prior_HadCM_new_2PIC_SST_D47_monthly):2*len(mu_prior_HadCM_new_2PIC_SST_D47_monthly)]
mu_post_HadCM_new_2PIC_d18Oc = mu_post_HadCM_new_2PIC[2*len(mu_prior_HadCM_new_2PIC_SST_D47_monthly):3*len(mu_prior_HadCM_new_2PIC_SST_D47_monthly)]
mu_post_HadCM_new_2PIC_precip = mu_post_HadCM_new_2PIC[3*len(mu_prior_HadCM_new_2PIC_d18Oc_monthly):]
# Extract the updated covariance matrices from the combined covariance matrix
cov_post_HadCM_new_2PIC_SST_D47 = cov_post_HadCM_new_2PIC[:len(mu_prior_HadCM_new_2PIC_SST_D47_monthly), :len(mu_prior_HadCM_new_2PIC_SST_D47_monthly)]
cov_post_HadCM_new_2PIC_SAT_D47 = cov_post_HadCM_new_2PIC[len(mu_prior_HadCM_new_2PIC_SST_D47_monthly):2*len(mu_prior_HadCM_new_2PIC_SST_D47_monthly), len(mu_prior_HadCM_new_2PIC_SST_D47_monthly):2*len(mu_prior_HadCM_new_2PIC_SST_D47_monthly)]
cov_post_HadCM_new_2PIC_d18Oc = cov_post_HadCM_new_2PIC[2*len(mu_prior_HadCM_new_2PIC_SST_D47_monthly):3*len(mu_prior_HadCM_new_2PIC_SST_D47_monthly), 2*len(mu_prior_HadCM_new_2PIC_SST_D47_monthly):3*len(mu_prior_HadCM_new_2PIC_SST_D47_monthly)]
cov_post_HadCM_new_2PIC_precip = cov_post_HadCM_new_2PIC[3*len(mu_prior_HadCM_new_2PIC_d18Oc_monthly):, 3*len(mu_prior_HadCM_new_2PIC_d18Oc_monthly):]
for measurement in Lutetian_data_monthly_aggregated_dict: # Loop over measurements
# Track and update likelihood statistics
weighted_sum_HadCM_new_2PIC, effective_weights_total_HadCM_new_2PIC, n_update_HadCM_new_2PIC, monthly_aggregated_data = likelihood_statistics_multi(
weighted_sum_HadCM_new_2PIC,
effective_weights_total_HadCM_new_2PIC,
n_update_HadCM_new_2PIC,
monthly_aggregated_data,
measurement,
timestamp = "month_score",
timestamp_sd = "Month_err",
Variable_names = var_names,
Variable_names_SDs = var_SD_names
)
# Normalize the weighted_sum_HadCM_new_2PIC to obtain weighted mean
# Calculate inverse square root of the effective_weights_total_HadCM_new_2PIC to contain the weighted standard deviation
# Print likelihood statistics
print("Likelihood statistics:")
num_vars = len(var_names) # number of variables (e.g., D47, d18O)
num_bins_monthly = int(len(weighted_sum_HadCM_new_2PIC) / num_vars)
for var_idx, var_name in enumerate(var_names):
print(f"Results for variable: {var_name}")
for bin_idx in range(num_bins_monthly):
idx = var_idx * num_bins_monthly + bin_idx
if effective_weights_total_HadCM_new_2PIC[idx] is not None and effective_weights_total_HadCM_new_2PIC[idx] != 0:
mu_likelihood[idx] = weighted_sum_HadCM_new_2PIC[idx] / effective_weights_total_HadCM_new_2PIC[idx]
std_likelihood[idx] = np.sqrt(1 / effective_weights_total_HadCM_new_2PIC[idx])
else:
# If there are no data points for this bin, set the likelihood to NaN
mu_likelihood[idx] = np.nan
std_likelihood[idx] = np.nan
print(f" Bin {bin_idx + 1}:")
print(f" Weighted Average: {mu_likelihood[idx]}")
print(f" Aggregated Uncertainty: {std_likelihood[idx]}")
print(f" Number of Data Points: {n_update_HadCM_new_2PIC[idx]}")
print()
print("Original Prior Mean SST-D47 monthly:\n", mu_prior_HadCM_new_2PIC_SST_D47_monthly_original)
print("Original Prior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_new_2PIC_SST_D47_monthly_original)))
print("Updated Posterior Mean SST-D47 monthly:\n", mu_post_HadCM_new_2PIC_SST_D47)
print("Updated Posterior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_post_HadCM_new_2PIC_SST_D47)))
print("Original Prior Mean SAT-D47 monthly:\n", mu_prior_HadCM_new_2PIC_SAT_monthly_original)
print("Original Prior Standard Deviation SAT-D47 monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_new_2PIC_SAT_monthly_original)))
print("Updated Posterior Mean SAT-D47 monthly:\n", mu_post_HadCM_new_2PIC_SAT_D47)
print("Updated Posterior Standard Deviation SAT-D47 monthly:\n", np.sqrt(np.diag(cov_post_HadCM_new_2PIC_SAT_D47)))
print("Original Prior Mean d18Oc monthly:\n", mu_prior_HadCM_new_2PIC_d18Oc_monthly_original)
print("Original Prior Standard Deviation d18Oc monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_new_2PIC_d18Oc_monthly_original)))
print("Updated Posterior Mean d18Oc monthly:\n", mu_post_HadCM_new_2PIC_d18Oc)
print("Updated Posterior Standard Deviation d18Oc monthly:\n", np.sqrt(np.diag(cov_post_HadCM_new_2PIC_d18Oc)))
print("Original Prior Mean precipitation monthly:\n", mu_prior_HadCM_new_2PIC_precip_monthly_original)
print("Original Prior Standard Deviation precipitation monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_new_2PIC_precip_monthly_original)))
print("Updated Posterior Mean precipitation monthly:\n", mu_post_HadCM_new_2PIC_precip)
print("Updated Posterior Standard Deviation precipitation monthly:\n", np.sqrt(np.diag(cov_post_HadCM_new_2PIC_precip)))
Likelihood statistics:
Results for variable: D47_mean
Bin 1:
Weighted Average: 0.6315000000000001
Aggregated Uncertainty: 0.0145
Number of Data Points: 1.0
Bin 2:
Weighted Average: 0.5964285714285714
Aggregated Uncertainty: 0.01096096971726759
Number of Data Points: 1.0
Bin 3:
Weighted Average: 0.6065
Aggregated Uncertainty: 0.010253048327204941
Number of Data Points: 1.0
Bin 4:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 5:
Weighted Average: 0.5749687499999999
Aggregated Uncertainty: 0.0051265241636024705
Number of Data Points: 1.0
Bin 6:
Weighted Average: 0.5925625
Aggregated Uncertainty: 0.00725
Number of Data Points: 1.0
Bin 7:
Weighted Average: 0.5888260869565218
Aggregated Uncertainty: 0.004275816728492018
Number of Data Points: 1.0
Bin 8:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 9:
Weighted Average: 0.5830000000000001
Aggregated Uncertainty: 0.004973458969132757
Number of Data Points: 1.0
Bin 10:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 11:
Weighted Average: 0.594
Aggregated Uncertainty: 0.011839200423452026
Number of Data Points: 1.0
Bin 12:
Weighted Average: 0.5921333333333333
Aggregated Uncertainty: 0.007487767802667672
Number of Data Points: 1.0
Results for variable: d18O
Bin 1:
Weighted Average: 0.016000000000000014
Aggregated Uncertainty: 0.0447213595499958
Number of Data Points: 1.0
Bin 2:
Weighted Average: 0.10700000000000001
Aggregated Uncertainty: 0.0316227766016838
Number of Data Points: 1.0
Bin 3:
Weighted Average: -0.22615384615384615
Aggregated Uncertainty: 0.02773500981126146
Number of Data Points: 1.0
Bin 4:
Weighted Average: -0.5469999999999999
Aggregated Uncertainty: 0.01414213562373095
Number of Data Points: 1.0
Bin 5:
Weighted Average: -1.2017647058823526
Aggregated Uncertainty: 0.009166984970282115
Number of Data Points: 1.0
Bin 6:
Weighted Average: -1.6498290598290601
Aggregated Uncertainty: 0.009245003270420488
Number of Data Points: 1.0
Bin 7:
Weighted Average: -2.0610810810810816
Aggregated Uncertainty: 0.009491579957524992
Number of Data Points: 1.0
Bin 8:
Weighted Average: -1.7621904761904763
Aggregated Uncertainty: 0.009759000729485335
Number of Data Points: 1.0
Bin 9:
Weighted Average: -1.3562711864406782
Aggregated Uncertainty: 0.009205746178983237
Number of Data Points: 1.0
Bin 10:
Weighted Average: -0.5620833333333334
Aggregated Uncertainty: 0.014433756729740647
Number of Data Points: 1.0
Bin 11:
Weighted Average: -0.06419354838709676
Aggregated Uncertainty: 0.017960530202677495
Number of Data Points: 1.0
Bin 12:
Weighted Average: -0.162
Aggregated Uncertainty: 0.0223606797749979
Number of Data Points: 1.0
Original Prior Mean SST-D47 monthly:
[0.61875389 0.62144134 0.62169674 0.61911904 0.61021893 0.59447415
0.58422233 0.58195388 0.58646513 0.59640058 0.60652689 0.6140889 ]
Original Prior Standard Deviation SST-D47 monthly:
[0.01040204 0.0109815 0.01071872 0.00954875 0.00690416 0.00357276
0.0021291 0.00205074 0.00405515 0.00645973 0.00802654 0.00939622]
Updated Posterior Mean SST-D47 monthly:
[0.61113523 0.61445579 0.61847325 0.61911904 0.61474574 0.59844603
0.58550682 0.58195388 0.58620523 0.59640058 0.60399661 0.60847355]
Updated Posterior Standard Deviation SST-D47 monthly:
[7.28066386e-04 7.51791821e-04 4.53569647e-04 nan
5.24531844e-04 7.42927977e-04 2.40789615e-04 8.73114914e-11
1.39860920e-04 nan 3.05217858e-04 4.57073846e-04]
Original Prior Mean SAT-D47 monthly:
[13.87478027 13.46100006 14.24293162 15.6019455 19.14669444 24.01290283
27.19336853 27.86939901 26.06070608 22.21917877 18.0738032 15.42517497]
Original Prior Standard Deviation SAT-D47 monthly:
[3.41347899 3.22229019 2.87469713 2.50385319 1.86477108 0.98233555
0.60279527 0.70411706 1.43557583 2.29931143 2.93579974 3.37321414]
Updated Posterior Mean SAT-D47 monthly:
[0.60476992 0.60636119 0.60397325 0.59975206 0.59206809 0.58318837
0.57547163 0.57449337 0.57672616 0.58354035 0.59410683 0.60049259]
Updated Posterior Standard Deviation SAT-D47 monthly:
[0.00080618 0.00082199 0.00081947 0.00092336 0.00103791 0.00080346
0.0004974 0.00039912 0.00054103 0.00070553 0.0008199 0.00085221]
Original Prior Mean d18Oc monthly:
[ 1.34651655 1.53819119 1.55333874 1.36348944 0.70137078 -0.48997468
-1.28354475 -1.47094578 -1.10453 -0.31671952 0.4525012 1.00989248]
Original Prior Standard Deviation d18Oc monthly:
[0.63262645 0.66808051 0.64945684 0.57332803 0.39872414 0.16768838
0.11737359 0.11506852 0.2109833 0.38622828 0.48685033 0.57123617]
Updated Posterior Mean d18Oc monthly:
[ 0.07829132 0.2587271 0.25832613 0.07199784 -0.3699015 -1.19892008
-1.83252468 -1.8512603 -1.71970195 -1.27483028 -0.61579703 -0.18889576]
Updated Posterior Standard Deviation d18Oc monthly:
[0.04499777 0.04762118 0.04199768 0.04114147 0.04705045 0.0472996
0.0421032 0.03960723 0.02881555 0.03221767 0.04247287 0.04588428]
Original Prior Mean precipitation monthly:
[3.80580454 3.16736692 2.40405854 2.33888872 2.90959791 1.9625486
3.35601807 3.95611436 3.35655003 3.81088675 4.52821999 4.18951223]
Original Prior Standard Deviation precipitation monthly:
[0.74624594 0.55008635 0.35552588 0.43694453 1.02178189 1.04182468
1.29200533 1.14999034 0.7361767 0.88765985 0.78936416 0.72873753]
Updated Posterior Mean precipitation monthly:
[7.98378055 6.11711225 3.74212789 3.40646899 3.37132175 0.67361506
6.62209357 9.59845192 7.08947814 7.17663163 9.42631991 8.18922726]
Updated Posterior Standard Deviation precipitation monthly:
[0.41640318 0.33531479 0.25143332 0.24371404 0.31880486 0.33027699
0.35702858 0.46088042 0.52869844 0.52717301 0.55469325 0.4343936 ]
C:\Users\nwi213\AppData\Local\Temp\ipykernel_4724\414881667.py:74: RuntimeWarning: invalid value encountered in sqrt
print("Updated Posterior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_post_HadCM_new_2PIC_SST_D47)))
Update monthly priors from HadCM (new) 1056 ppm pCO2 with aggregated data¶
- Data and model outcomes aggregated in 12 months
- No sclero-dating uncertainty
- D47 Data aggregated per specimen and per month
In [69]:
# Apply Kalman function to update the prior with monthly data including updating the prec estimates
# Update the monthly D47 and prec prior with all measurements using block updating
monthly_aggregated_data = {} # Keep track of datapoints per season
n_update_HadCM_new_1056ppm = np.concatenate([mu_prior_HadCM_new_1056ppm_SST_D47_monthly * 0, mu_prior_HadCM_new_1056ppm_d18Oc_monthly * 0]) # Vector to store sample size per season for confidence interval plotting
weighted_sum_HadCM_new_1056ppm = np.concatenate([mu_prior_HadCM_new_1056ppm_SST_D47_monthly * 0, mu_prior_HadCM_new_1056ppm_d18Oc_monthly * 0]) # Vector to store mean temperature per season for confidence interval plotting
effective_weights_total_HadCM_new_1056ppm = np.concatenate([mu_prior_HadCM_new_1056ppm_SST_D47_monthly * 0, mu_prior_HadCM_new_1056ppm_d18Oc_monthly * 0]) # Vector to store temperature uncertainty per season for confidence interval plotting
mu_likelihood = np.concatenate([mu_prior_HadCM_new_1056ppm_SST_D47_monthly * 0, mu_prior_HadCM_new_1056ppm_d18Oc_monthly * 0]) # Vector to store mean temperature per season for confidence interval plotting
std_likelihood = np.concatenate([mu_prior_HadCM_new_1056ppm_SST_D47_monthly * 0, mu_prior_HadCM_new_1056ppm_d18Oc_monthly * 0]) # Vector to store temperature uncertainty per season for confidence interval plotting
var_names = ["D47_mean", "d18O"] # List of variable names which are updated
var_SD_names = ["D47_SD", "d18O_SD"] # List of names of variable uncertainties which are updated
# Update the prior with monthly data using the Kalman filter in block updating form
mu_post_HadCM_new_1056ppm, cov_post_HadCM_new_1056ppm = kalman_update_block(
mu_prior_HadCM_new_1056ppm_monthly_combined,
cov_prior_HadCM_new_1056ppm_monthly_combined,
Z,
R,
H
)
# Extract the updated mean values from the combined state vector
mu_post_HadCM_new_1056ppm_SST_D47 = mu_post_HadCM_new_1056ppm[:len(mu_prior_HadCM_new_1056ppm_SST_D47_monthly)]
mu_post_HadCM_new_1056ppm_SAT_D47 = mu_post_HadCM_new_1056ppm[len(mu_prior_HadCM_new_1056ppm_SST_D47_monthly):2*len(mu_prior_HadCM_new_1056ppm_SST_D47_monthly)]
mu_post_HadCM_new_1056ppm_d18Oc = mu_post_HadCM_new_1056ppm[2*len(mu_prior_HadCM_new_1056ppm_SST_D47_monthly):3*len(mu_prior_HadCM_new_1056ppm_SST_D47_monthly)]
mu_post_HadCM_new_1056ppm_precip = mu_post_HadCM_new_1056ppm[3*len(mu_prior_HadCM_new_1056ppm_d18Oc_monthly):]
# Extract the updated covariance matrices from the combined covariance matrix
cov_post_HadCM_new_1056ppm_SST_D47 = cov_post_HadCM_new_1056ppm[:len(mu_prior_HadCM_new_1056ppm_SST_D47_monthly), :len(mu_prior_HadCM_new_1056ppm_SST_D47_monthly)]
cov_post_HadCM_new_1056ppm_SAT_D47 = cov_post_HadCM_new_1056ppm[len(mu_prior_HadCM_new_1056ppm_SST_D47_monthly):2*len(mu_prior_HadCM_new_1056ppm_SST_D47_monthly), len(mu_prior_HadCM_new_1056ppm_SST_D47_monthly):2*len(mu_prior_HadCM_new_1056ppm_SST_D47_monthly)]
cov_post_HadCM_new_1056ppm_d18Oc = cov_post_HadCM_new_1056ppm[2*len(mu_prior_HadCM_new_1056ppm_SST_D47_monthly):3*len(mu_prior_HadCM_new_1056ppm_SST_D47_monthly), 2*len(mu_prior_HadCM_new_1056ppm_SST_D47_monthly):3*len(mu_prior_HadCM_new_1056ppm_SST_D47_monthly)]
cov_post_HadCM_new_1056ppm_precip = cov_post_HadCM_new_1056ppm[3*len(mu_prior_HadCM_new_1056ppm_d18Oc_monthly):, 3*len(mu_prior_HadCM_new_1056ppm_d18Oc_monthly):]
for measurement in Lutetian_data_monthly_aggregated_dict: # Loop over measurements
# Track and update likelihood statistics
weighted_sum_HadCM_new_1056ppm, effective_weights_total_HadCM_new_1056ppm, n_update_HadCM_new_1056ppm, monthly_aggregated_data = likelihood_statistics_multi(
weighted_sum_HadCM_new_1056ppm,
effective_weights_total_HadCM_new_1056ppm,
n_update_HadCM_new_1056ppm,
monthly_aggregated_data,
measurement,
timestamp = "month_score",
timestamp_sd = "Month_err",
Variable_names = var_names,
Variable_names_SDs = var_SD_names
)
# Normalize the weighted_sum_HadCM_new_1056ppm to obtain weighted mean
# Calculate inverse square root of the effective_weights_total_HadCM_new_1056ppm to contain the weighted standard deviation
# Print likelihood statistics
print("Likelihood statistics:")
num_vars = len(var_names) # number of variables (e.g., D47, d18O)
num_bins_monthly = int(len(weighted_sum_HadCM_new_1056ppm) / num_vars)
for var_idx, var_name in enumerate(var_names):
print(f"Results for variable: {var_name}")
for bin_idx in range(num_bins_monthly):
idx = var_idx * num_bins_monthly + bin_idx
if effective_weights_total_HadCM_new_1056ppm[idx] is not None and effective_weights_total_HadCM_new_1056ppm[idx] != 0:
mu_likelihood[idx] = weighted_sum_HadCM_new_1056ppm[idx] / effective_weights_total_HadCM_new_1056ppm[idx]
std_likelihood[idx] = np.sqrt(1 / effective_weights_total_HadCM_new_1056ppm[idx])
else:
# If there are no data points for this bin, set the likelihood to NaN
mu_likelihood[idx] = np.nan
std_likelihood[idx] = np.nan
print(f" Bin {bin_idx + 1}:")
print(f" Weighted Average: {mu_likelihood[idx]}")
print(f" Aggregated Uncertainty: {std_likelihood[idx]}")
print(f" Number of Data Points: {n_update_HadCM_new_1056ppm[idx]}")
print()
print("Original Prior Mean SST-D47 monthly:\n", mu_prior_HadCM_new_1056ppm_SST_D47_monthly_original)
print("Original Prior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_new_1056ppm_SST_D47_monthly_original)))
print("Updated Posterior Mean SST-D47 monthly:\n", mu_post_HadCM_new_1056ppm_SST_D47)
print("Updated Posterior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_post_HadCM_new_1056ppm_SST_D47)))
print("Original Prior Mean SAT-D47 monthly:\n", mu_prior_HadCM_new_1056ppm_SAT_monthly_original)
print("Original Prior Standard Deviation SAT-D47 monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_new_1056ppm_SAT_monthly_original)))
print("Updated Posterior Mean SAT-D47 monthly:\n", mu_post_HadCM_new_1056ppm_SAT_D47)
print("Updated Posterior Standard Deviation SAT-D47 monthly:\n", np.sqrt(np.diag(cov_post_HadCM_new_1056ppm_SAT_D47)))
print("Original Prior Mean d18Oc monthly:\n", mu_prior_HadCM_new_1056ppm_d18Oc_monthly_original)
print("Original Prior Standard Deviation d18Oc monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_new_1056ppm_d18Oc_monthly_original)))
print("Updated Posterior Mean d18Oc monthly:\n", mu_post_HadCM_new_1056ppm_d18Oc)
print("Updated Posterior Standard Deviation d18Oc monthly:\n", np.sqrt(np.diag(cov_post_HadCM_new_1056ppm_d18Oc)))
print("Original Prior Mean precipitation monthly:\n", mu_prior_HadCM_new_1056ppm_precip_monthly_original)
print("Original Prior Standard Deviation precipitation monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_new_1056ppm_precip_monthly_original)))
print("Updated Posterior Mean precipitation monthly:\n", mu_post_HadCM_new_1056ppm_precip)
print("Updated Posterior Standard Deviation precipitation monthly:\n", np.sqrt(np.diag(cov_post_HadCM_new_1056ppm_precip)))
Likelihood statistics:
Results for variable: D47_mean
Bin 1:
Weighted Average: 0.6315000000000001
Aggregated Uncertainty: 0.0145
Number of Data Points: 1.0
Bin 2:
Weighted Average: 0.5964285714285714
Aggregated Uncertainty: 0.01096096971726759
Number of Data Points: 1.0
Bin 3:
Weighted Average: 0.6065
Aggregated Uncertainty: 0.010253048327204941
Number of Data Points: 1.0
Bin 4:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 5:
Weighted Average: 0.5749687499999999
Aggregated Uncertainty: 0.0051265241636024705
Number of Data Points: 1.0
Bin 6:
Weighted Average: 0.5925625
Aggregated Uncertainty: 0.00725
Number of Data Points: 1.0
Bin 7:
Weighted Average: 0.5888260869565218
Aggregated Uncertainty: 0.004275816728492018
Number of Data Points: 1.0
Bin 8:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 9:
Weighted Average: 0.5830000000000001
Aggregated Uncertainty: 0.004973458969132757
Number of Data Points: 1.0
Bin 10:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 11:
Weighted Average: 0.594
Aggregated Uncertainty: 0.011839200423452026
Number of Data Points: 1.0
Bin 12:
Weighted Average: 0.5921333333333333
Aggregated Uncertainty: 0.007487767802667672
Number of Data Points: 1.0
Results for variable: d18O
Bin 1:
Weighted Average: 0.016000000000000014
Aggregated Uncertainty: 0.0447213595499958
Number of Data Points: 1.0
Bin 2:
Weighted Average: 0.10700000000000001
Aggregated Uncertainty: 0.0316227766016838
Number of Data Points: 1.0
Bin 3:
Weighted Average: -0.22615384615384615
Aggregated Uncertainty: 0.02773500981126146
Number of Data Points: 1.0
Bin 4:
Weighted Average: -0.5469999999999999
Aggregated Uncertainty: 0.01414213562373095
Number of Data Points: 1.0
Bin 5:
Weighted Average: -1.2017647058823526
Aggregated Uncertainty: 0.009166984970282115
Number of Data Points: 1.0
Bin 6:
Weighted Average: -1.6498290598290601
Aggregated Uncertainty: 0.009245003270420488
Number of Data Points: 1.0
Bin 7:
Weighted Average: -2.0610810810810816
Aggregated Uncertainty: 0.009491579957524992
Number of Data Points: 1.0
Bin 8:
Weighted Average: -1.7621904761904763
Aggregated Uncertainty: 0.009759000729485335
Number of Data Points: 1.0
Bin 9:
Weighted Average: -1.3562711864406782
Aggregated Uncertainty: 0.009205746178983237
Number of Data Points: 1.0
Bin 10:
Weighted Average: -0.5620833333333334
Aggregated Uncertainty: 0.014433756729740647
Number of Data Points: 1.0
Bin 11:
Weighted Average: -0.06419354838709676
Aggregated Uncertainty: 0.017960530202677495
Number of Data Points: 1.0
Bin 12:
Weighted Average: -0.162
Aggregated Uncertainty: 0.0223606797749979
Number of Data Points: 1.0
Original Prior Mean SST-D47 monthly:
[0.61178805 0.61408643 0.61450653 0.61183965 0.60351899 0.58890726
0.57896879 0.57614968 0.58012824 0.58940847 0.60010733 0.60731336]
Original Prior Standard Deviation SST-D47 monthly:
[0.00950473 0.00991746 0.00975143 0.00855046 0.00601008 0.00264934
0.001987 0.00193393 0.00336092 0.00555588 0.00726523 0.00854462]
Updated Posterior Mean SST-D47 monthly:
[0.6059617 0.60965206 0.61117591 0.61183965 0.60699861 0.5936751
0.58146936 0.57614968 0.58006555 0.58940847 0.59723649 0.60229133]
Updated Posterior Standard Deviation SST-D47 monthly:
[7.37920109e-04 6.45206398e-04 4.07501316e-04 5.76226444e-10
4.23070544e-04 6.43039061e-04 3.00159791e-04 4.11590317e-11
1.45475116e-04 8.23180635e-10 2.96105409e-04 5.37685293e-04]
Original Prior Mean SAT-D47 monthly:
[16.54376119 16.33315684 16.66519572 18.1570933 21.33070018 26.04470978
29.27867788 30.05242564 28.38777822 24.68946991 20.37269491 17.89802958]
Original Prior Standard Deviation SAT-D47 monthly:
[3.1136452 2.87241146 2.6653854 2.24775679 1.63278962 0.69198219
0.47930615 0.56291876 1.14972847 2.03401859 2.74423138 3.08483859]
Updated Posterior Mean SAT-D47 monthly:
[0.60433745 0.60479057 0.60292906 0.59708906 0.5891163 0.58062087
0.57349845 0.5721597 0.57390406 0.58219882 0.59359416 0.60009983]
Updated Posterior Standard Deviation SAT-D47 monthly:
[0.00081662 0.00080777 0.00081614 0.00093723 0.00099199 0.00075654
0.00052592 0.00035384 0.00049973 0.00063044 0.00078469 0.00084532]
Original Prior Mean d18Oc monthly:
[ 0.89938202 1.06227796 1.09074434 0.89304546 0.26814927 -0.85652748
-1.63310083 -1.85641729 -1.52480304 -0.78486291 0.03877691 0.57421982]
Original Prior Standard Deviation d18Oc monthly:
[0.58354349 0.60848538 0.59658837 0.51493414 0.33894432 0.09898967
0.16122308 0.13822702 0.15000845 0.32013947 0.4397222 0.52235491]
Updated Posterior Mean d18Oc monthly:
[ 0.15197295 0.26100485 0.21607202 -0.05770915 -0.54535977 -1.29778997
-1.86136787 -1.92176705 -1.82082829 -1.29126878 -0.5693999 -0.13270156]
Updated Posterior Standard Deviation d18Oc monthly:
[0.04367811 0.04251691 0.04035924 0.04344383 0.0457741 0.04436709
0.04601354 0.04063306 0.02606902 0.03079696 0.04333981 0.04545931]
Original Prior Mean precipitation monthly:
[4.56713648 3.91851193 2.74238199 2.21756103 2.6688204 2.25554827
2.59721839 3.43563859 3.46278601 4.34280869 4.56264103 4.84894508]
Original Prior Standard Deviation precipitation monthly:
[0.85407461 0.70612807 0.50598617 0.43407756 1.00076624 1.0245456
1.00411221 1.11605905 0.828573 1.1991117 0.95570044 1.00690122]
Updated Posterior Mean precipitation monthly:
[8.59834819 7.40964913 5.08979493 3.61994327 3.35145921 1.66313621
2.59151062 5.22696667 7.05816581 7.44125433 8.5142906 9.51385992]
Updated Posterior Standard Deviation precipitation monthly:
[0.57092592 0.46340285 0.32062732 0.25540271 0.3659027 0.41046382
0.42360275 0.57144701 0.62346658 0.60559179 0.56482241 0.59676163]
Update monthly priors from HadCM (old) 2x preindustrial pCO2 with aggregated data¶
- Data and model outcomes aggregated in 12 months
- No sclero-dating uncertainty
- D47 Data aggregated per specimen and per month
In [70]:
# Apply Kalman function to update the prior with monthly data including updating the prec estimates
# Update the monthly D47 and prec prior with all measurements using block updating
monthly_aggregated_data = {} # Keep track of datapoints per season
n_update_HadCM_old_2PIC = np.concatenate([mu_prior_HadCM_old_2PIC_SST_D47_monthly * 0, mu_prior_HadCM_old_2PIC_d18Oc_monthly * 0]) # Vector to store sample size per season for confidence interval plotting
weighted_sum_HadCM_old_2PIC = np.concatenate([mu_prior_HadCM_old_2PIC_SST_D47_monthly * 0, mu_prior_HadCM_old_2PIC_d18Oc_monthly * 0]) # Vector to store mean temperature per season for confidence interval plotting
effective_weights_total_HadCM_old_2PIC = np.concatenate([mu_prior_HadCM_old_2PIC_SST_D47_monthly * 0, mu_prior_HadCM_old_2PIC_d18Oc_monthly * 0]) # Vector to store temperature uncertainty per season for confidence interval plotting
mu_likelihood = np.concatenate([mu_prior_HadCM_old_2PIC_SST_D47_monthly * 0, mu_prior_HadCM_old_2PIC_d18Oc_monthly * 0]) # Vector to store mean temperature per season for confidence interval plotting
std_likelihood = np.concatenate([mu_prior_HadCM_old_2PIC_SST_D47_monthly * 0, mu_prior_HadCM_old_2PIC_d18Oc_monthly * 0]) # Vector to store temperature uncertainty per season for confidence interval plotting
var_names = ["D47_mean", "d18O"] # List of variable names which are updated
var_SD_names = ["D47_SD", "d18O_SD"] # List of names of variable uncertainties which are updated
# Update the prior with monthly data using the Kalman filter in block updating form
mu_post_HadCM_old_2PIC, cov_post_HadCM_old_2PIC = kalman_update_block(
mu_prior_HadCM_old_2PIC_monthly_combined,
cov_prior_HadCM_old_2PIC_monthly_combined,
Z,
R,
H
)
# Extract the updated mean values from the combined state vector
mu_post_HadCM_old_2PIC_SST_D47 = mu_post_HadCM_old_2PIC[:len(mu_prior_HadCM_old_2PIC_SST_D47_monthly)]
mu_post_HadCM_old_2PIC_SAT_D47 = mu_post_HadCM_old_2PIC[len(mu_prior_HadCM_old_2PIC_SST_D47_monthly):2*len(mu_prior_HadCM_old_2PIC_SST_D47_monthly)]
mu_post_HadCM_old_2PIC_d18Oc = mu_post_HadCM_old_2PIC[2*len(mu_prior_HadCM_old_2PIC_SST_D47_monthly):3*len(mu_prior_HadCM_old_2PIC_SST_D47_monthly)]
mu_post_HadCM_old_2PIC_precip = mu_post_HadCM_old_2PIC[3*len(mu_prior_HadCM_old_2PIC_d18Oc_monthly):]
# Extract the updated covariance matrices from the combined covariance matrix
cov_post_HadCM_old_2PIC_SST_D47 = cov_post_HadCM_old_2PIC[:len(mu_prior_HadCM_old_2PIC_SST_D47_monthly), :len(mu_prior_HadCM_old_2PIC_SST_D47_monthly)]
cov_post_HadCM_old_2PIC_SAT_D47 = cov_post_HadCM_old_2PIC[len(mu_prior_HadCM_old_2PIC_SST_D47_monthly):2*len(mu_prior_HadCM_old_2PIC_SST_D47_monthly), len(mu_prior_HadCM_old_2PIC_SST_D47_monthly):2*len(mu_prior_HadCM_old_2PIC_SST_D47_monthly)]
cov_post_HadCM_old_2PIC_d18Oc = cov_post_HadCM_old_2PIC[2*len(mu_prior_HadCM_old_2PIC_SST_D47_monthly):3*len(mu_prior_HadCM_old_2PIC_SST_D47_monthly), 2*len(mu_prior_HadCM_old_2PIC_SST_D47_monthly):3*len(mu_prior_HadCM_old_2PIC_SST_D47_monthly)]
cov_post_HadCM_old_2PIC_precip = cov_post_HadCM_old_2PIC[3*len(mu_prior_HadCM_old_2PIC_d18Oc_monthly):, 3*len(mu_prior_HadCM_old_2PIC_d18Oc_monthly):]
for measurement in Lutetian_data_monthly_aggregated_dict: # Loop over measurements
# Track and update likelihood statistics
weighted_sum_HadCM_old_2PIC, effective_weights_total_HadCM_old_2PIC, n_update_HadCM_old_2PIC, monthly_aggregated_data = likelihood_statistics_multi(
weighted_sum_HadCM_old_2PIC,
effective_weights_total_HadCM_old_2PIC,
n_update_HadCM_old_2PIC,
monthly_aggregated_data,
measurement,
timestamp = "month_score",
timestamp_sd = "Month_err",
Variable_names = var_names,
Variable_names_SDs = var_SD_names
)
# Normalize the weighted_sum_HadCM_old_2PIC to obtain weighted mean
# Calculate inverse square root of the effective_weights_total_HadCM_old_2PIC to contain the weighted standard deviation
# Print likelihood statistics
print("Likelihood statistics:")
num_vars = len(var_names) # number of variables (e.g., D47, d18O)
num_bins_monthly = int(len(weighted_sum_HadCM_old_2PIC) / num_vars)
for var_idx, var_name in enumerate(var_names):
print(f"Results for variable: {var_name}")
for bin_idx in range(num_bins_monthly):
idx = var_idx * num_bins_monthly + bin_idx
if effective_weights_total_HadCM_old_2PIC[idx] is not None and effective_weights_total_HadCM_old_2PIC[idx] != 0:
mu_likelihood[idx] = weighted_sum_HadCM_old_2PIC[idx] / effective_weights_total_HadCM_old_2PIC[idx]
std_likelihood[idx] = np.sqrt(1 / effective_weights_total_HadCM_old_2PIC[idx])
else:
# If there are no data points for this bin, set the likelihood to NaN
mu_likelihood[idx] = np.nan
std_likelihood[idx] = np.nan
print(f" Bin {bin_idx + 1}:")
print(f" Weighted Average: {mu_likelihood[idx]}")
print(f" Aggregated Uncertainty: {std_likelihood[idx]}")
print(f" Number of Data Points: {n_update_HadCM_old_2PIC[idx]}")
print()
print("Original Prior Mean SST-D47 monthly:\n", mu_prior_HadCM_old_2PIC_SST_D47_monthly_original)
print("Original Prior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_old_2PIC_SST_D47_monthly_original)))
print("Updated Posterior Mean SST-D47 monthly:\n", mu_post_HadCM_old_2PIC_SST_D47)
print("Updated Posterior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_post_HadCM_old_2PIC_SST_D47)))
print("Original Prior Mean SAT-D47 monthly:\n", mu_prior_HadCM_old_2PIC_SAT_monthly_original)
print("Original Prior Standard Deviation SAT-D47 monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_old_2PIC_SAT_monthly_original)))
print("Updated Posterior Mean SAT-D47 monthly:\n", mu_post_HadCM_old_2PIC_SAT_D47)
print("Updated Posterior Standard Deviation SAT-D47 monthly:\n", np.sqrt(np.diag(cov_post_HadCM_old_2PIC_SAT_D47)))
print("Original Prior Mean d18Oc monthly:\n", mu_prior_HadCM_old_2PIC_d18Oc_monthly_original)
print("Original Prior Standard Deviation d18Oc monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_old_2PIC_d18Oc_monthly_original)))
print("Updated Posterior Mean d18Oc monthly:\n", mu_post_HadCM_old_2PIC_d18Oc)
print("Updated Posterior Standard Deviation d18Oc monthly:\n", np.sqrt(np.diag(cov_post_HadCM_old_2PIC_d18Oc)))
print("Original Prior Mean precipitation monthly:\n", mu_prior_HadCM_old_2PIC_precip_monthly_original)
print("Original Prior Standard Deviation precipitation monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_old_2PIC_precip_monthly_original)))
print("Updated Posterior Mean precipitation monthly:\n", mu_post_HadCM_old_2PIC_precip)
print("Updated Posterior Standard Deviation precipitation monthly:\n", np.sqrt(np.diag(cov_post_HadCM_old_2PIC_precip)))
Likelihood statistics:
Results for variable: D47_mean
Bin 1:
Weighted Average: 0.6315000000000001
Aggregated Uncertainty: 0.0145
Number of Data Points: 1.0
Bin 2:
Weighted Average: 0.5964285714285714
Aggregated Uncertainty: 0.01096096971726759
Number of Data Points: 1.0
Bin 3:
Weighted Average: 0.6065
Aggregated Uncertainty: 0.010253048327204941
Number of Data Points: 1.0
Bin 4:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 5:
Weighted Average: 0.5749687499999999
Aggregated Uncertainty: 0.0051265241636024705
Number of Data Points: 1.0
Bin 6:
Weighted Average: 0.5925625
Aggregated Uncertainty: 0.00725
Number of Data Points: 1.0
Bin 7:
Weighted Average: 0.5888260869565218
Aggregated Uncertainty: 0.004275816728492018
Number of Data Points: 1.0
Bin 8:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 9:
Weighted Average: 0.5830000000000001
Aggregated Uncertainty: 0.004973458969132757
Number of Data Points: 1.0
Bin 10:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 11:
Weighted Average: 0.594
Aggregated Uncertainty: 0.011839200423452026
Number of Data Points: 1.0
Bin 12:
Weighted Average: 0.5921333333333333
Aggregated Uncertainty: 0.007487767802667672
Number of Data Points: 1.0
Results for variable: d18O
Bin 1:
Weighted Average: 0.016000000000000014
Aggregated Uncertainty: 0.0447213595499958
Number of Data Points: 1.0
Bin 2:
Weighted Average: 0.10700000000000001
Aggregated Uncertainty: 0.0316227766016838
Number of Data Points: 1.0
Bin 3:
Weighted Average: -0.22615384615384615
Aggregated Uncertainty: 0.02773500981126146
Number of Data Points: 1.0
Bin 4:
Weighted Average: -0.5469999999999999
Aggregated Uncertainty: 0.01414213562373095
Number of Data Points: 1.0
Bin 5:
Weighted Average: -1.2017647058823526
Aggregated Uncertainty: 0.009166984970282115
Number of Data Points: 1.0
Bin 6:
Weighted Average: -1.6498290598290601
Aggregated Uncertainty: 0.009245003270420488
Number of Data Points: 1.0
Bin 7:
Weighted Average: -2.0610810810810816
Aggregated Uncertainty: 0.009491579957524992
Number of Data Points: 1.0
Bin 8:
Weighted Average: -1.7621904761904763
Aggregated Uncertainty: 0.009759000729485335
Number of Data Points: 1.0
Bin 9:
Weighted Average: -1.3562711864406782
Aggregated Uncertainty: 0.009205746178983237
Number of Data Points: 1.0
Bin 10:
Weighted Average: -0.5620833333333334
Aggregated Uncertainty: 0.014433756729740647
Number of Data Points: 1.0
Bin 11:
Weighted Average: -0.06419354838709676
Aggregated Uncertainty: 0.017960530202677495
Number of Data Points: 1.0
Bin 12:
Weighted Average: -0.162
Aggregated Uncertainty: 0.0223606797749979
Number of Data Points: 1.0
Original Prior Mean SST-D47 monthly:
[0.60952059 0.61177987 0.61211207 0.60890818 0.59999147 0.58762014
0.57910703 0.57497457 0.5767857 0.58612855 0.59672445 0.60499141]
Original Prior Standard Deviation SST-D47 monthly:
[0.00730275 0.00751657 0.00756292 0.00688203 0.00519937 0.00330025
0.00165647 0.00170597 0.00223992 0.00457919 0.0061014 0.00687984]
Updated Posterior Mean SST-D47 monthly:
[0.60929279 0.61110217 0.61146843 0.60890818 0.60132146 0.59679646
0.5913868 0.57497457 0.570493 0.58612855 0.59963663 0.60529398]
Updated Posterior Standard Deviation SST-D47 monthly:
[4.06383364e-04 3.17817205e-04 2.03849021e-04 3.29272254e-10
3.16315655e-04 7.34458148e-04 6.69732097e-04 nan
3.03903741e-04 3.86105942e-10 2.61070761e-04 4.46781687e-04]
Original Prior Mean SAT-D47 monthly:
[17.37342478 17.21628214 17.78856557 19.24039866 22.18971914 26.23706462
29.33261007 30.70993194 29.73895416 26.07219594 21.69050496 18.52393239]
Original Prior Standard Deviation SAT-D47 monthly:
[3.2114442 2.69102368 2.25082291 1.96523166 1.63807297 1.35401718
0.73510388 0.49971448 0.91035189 1.98977278 2.90543435 3.37134836]
Updated Posterior Mean SAT-D47 monthly:
[0.59961509 0.59806084 0.59560856 0.59335018 0.58767151 0.57412668
0.56915225 0.57456599 0.5788128 0.58115739 0.59084795 0.59835057]
Updated Posterior Standard Deviation SAT-D47 monthly:
[0.00141255 0.00136087 0.00132509 0.0012541 0.00116415 0.0010171
0.00093373 0.00091888 0.00085299 0.00101592 0.00124689 0.001419 ]
Original Prior Mean d18Oc monthly:
[ 2.610453 2.78266516 2.80531485 2.55561563 1.87962861 0.93728201
0.28135718 -0.03614475 0.1034491 0.83319401 1.64799416 2.27215511]
Original Prior Standard Deviation d18Oc monthly:
[0.36157545 0.37407513 0.37312685 0.32006347 0.21320302 0.15150899
0.19818414 0.24130267 0.10970853 0.19072319 0.29013312 0.33416273]
Updated Posterior Mean d18Oc monthly:
[ 0.10466442 0.18408074 0.15635633 0.02406903 -0.41678584 -1.41772702
-1.76512541 -1.35428154 -1.1531825 -1.12463334 -0.6287255 -0.13126015]
Updated Posterior Standard Deviation d18Oc monthly:
[0.04366004 0.04294683 0.04246724 0.04064485 0.04176134 0.05359773
0.05593455 0.05003228 0.03412996 0.03322553 0.0375173 0.04319486]
Original Prior Mean precipitation monthly:
[4.51414761 2.96477545 2.0466914 1.70405398 1.499306 0.98548384
1.2141631 1.94227658 3.96484522 4.89490475 5.10539876 4.79175341]
Original Prior Standard Deviation precipitation monthly:
[0.54851291 0.54980863 0.52847315 0.61988324 0.67752496 0.34351868
0.40517783 0.93230212 0.90520864 0.74675508 0.64169083 0.55874858]
Updated Posterior Mean precipitation monthly:
[ 5.78186312 2.53759874 2.42827759 3.3392642 4.79783349 3.08769232
-0.2446832 -1.10487115 5.96112349 8.00533232 2.18892769 5.62862659]
Updated Posterior Standard Deviation precipitation monthly:
[0.36594123 0.20462568 0.19978116 0.24788844 0.32308452 0.17565873
0.28027528 0.46830502 0.61994237 0.63269722 0.43719639 0.40715268]
C:\Users\nwi213\AppData\Local\Temp\ipykernel_4724\2718528581.py:74: RuntimeWarning: invalid value encountered in sqrt
print("Updated Posterior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_post_HadCM_old_2PIC_SST_D47)))
Update monthly priors from HadCM (old) 4x preindustrial pCO2 with aggregated data¶
- Data and model outcomes aggregated in 12 months
- No sclero-dating uncertainty
- D47 Data aggregated per specimen and per month
In [71]:
# Apply Kalman function to update the prior with monthly data including updating the prec estimates
# Update the monthly D47 and prec prior with all measurements using block updating
monthly_aggregated_data = {} # Keep track of datapoints per season
n_update_HadCM_old_4PIC = np.concatenate([mu_prior_HadCM_old_4PIC_SST_D47_monthly * 0, mu_prior_HadCM_old_4PIC_d18Oc_monthly * 0]) # Vector to store sample size per season for confidence interval plotting
weighted_sum_HadCM_old_4PIC = np.concatenate([mu_prior_HadCM_old_4PIC_SST_D47_monthly * 0, mu_prior_HadCM_old_4PIC_d18Oc_monthly * 0]) # Vector to store mean temperature per season for confidence interval plotting
effective_weights_total_HadCM_old_4PIC = np.concatenate([mu_prior_HadCM_old_4PIC_SST_D47_monthly * 0, mu_prior_HadCM_old_4PIC_d18Oc_monthly * 0]) # Vector to store temperature uncertainty per season for confidence interval plotting
mu_likelihood = np.concatenate([mu_prior_HadCM_old_4PIC_SST_D47_monthly * 0, mu_prior_HadCM_old_4PIC_d18Oc_monthly * 0]) # Vector to store mean temperature per season for confidence interval plotting
std_likelihood = np.concatenate([mu_prior_HadCM_old_4PIC_SST_D47_monthly * 0, mu_prior_HadCM_old_4PIC_d18Oc_monthly * 0]) # Vector to store temperature uncertainty per season for confidence interval plotting
var_names = ["D47_mean", "d18O"] # List of variable names which are updated
var_SD_names = ["D47_SD", "d18O_SD"] # List of names of variable uncertainties which are updated
# Update the prior with monthly data using the Kalman filter in block updating form
mu_post_HadCM_old_4PIC, cov_post_HadCM_old_4PIC = kalman_update_block(
mu_prior_HadCM_old_4PIC_monthly_combined,
cov_prior_HadCM_old_4PIC_monthly_combined,
Z,
R,
H
)
# Extract the updated mean values from the combined state vector
mu_post_HadCM_old_4PIC_SST_D47 = mu_post_HadCM_old_4PIC[:len(mu_prior_HadCM_old_4PIC_SST_D47_monthly)]
mu_post_HadCM_old_4PIC_SAT_D47 = mu_post_HadCM_old_4PIC[len(mu_prior_HadCM_old_4PIC_SST_D47_monthly):2*len(mu_prior_HadCM_old_4PIC_SST_D47_monthly)]
mu_post_HadCM_old_4PIC_d18Oc = mu_post_HadCM_old_4PIC[2*len(mu_prior_HadCM_old_4PIC_SST_D47_monthly):3*len(mu_prior_HadCM_old_4PIC_SST_D47_monthly)]
mu_post_HadCM_old_4PIC_precip = mu_post_HadCM_old_4PIC[3*len(mu_prior_HadCM_old_4PIC_d18Oc_monthly):]
# Extract the updated covariance matrices from the combined covariance matrix
cov_post_HadCM_old_4PIC_SST_D47 = cov_post_HadCM_old_4PIC[:len(mu_prior_HadCM_old_4PIC_SST_D47_monthly), :len(mu_prior_HadCM_old_4PIC_SST_D47_monthly)]
cov_post_HadCM_old_4PIC_SAT_D47 = cov_post_HadCM_old_4PIC[len(mu_prior_HadCM_old_4PIC_SST_D47_monthly):2*len(mu_prior_HadCM_old_4PIC_SST_D47_monthly), len(mu_prior_HadCM_old_4PIC_SST_D47_monthly):2*len(mu_prior_HadCM_old_4PIC_SST_D47_monthly)]
cov_post_HadCM_old_4PIC_d18Oc = cov_post_HadCM_old_4PIC[2*len(mu_prior_HadCM_old_4PIC_SST_D47_monthly):3*len(mu_prior_HadCM_old_4PIC_SST_D47_monthly), 2*len(mu_prior_HadCM_old_4PIC_SST_D47_monthly):3*len(mu_prior_HadCM_old_4PIC_SST_D47_monthly)]
cov_post_HadCM_old_4PIC_precip = cov_post_HadCM_old_4PIC[3*len(mu_prior_HadCM_old_4PIC_d18Oc_monthly):, 3*len(mu_prior_HadCM_old_4PIC_d18Oc_monthly):]
for measurement in Lutetian_data_monthly_aggregated_dict: # Loop over measurements
# Track and update likelihood statistics
weighted_sum_HadCM_old_4PIC, effective_weights_total_HadCM_old_4PIC, n_update_HadCM_old_4PIC, monthly_aggregated_data = likelihood_statistics_multi(
weighted_sum_HadCM_old_4PIC,
effective_weights_total_HadCM_old_4PIC,
n_update_HadCM_old_4PIC,
monthly_aggregated_data,
measurement,
timestamp = "month_score",
timestamp_sd = "Month_err",
Variable_names = var_names,
Variable_names_SDs = var_SD_names
)
# Normalize the weighted_sum_HadCM_old_4PIC to obtain weighted mean
# Calculate inverse square root of the effective_weights_total_HadCM_old_4PIC to contain the weighted standard deviation
# Print likelihood statistics
print("Likelihood statistics:")
num_vars = len(var_names) # number of variables (e.g., D47, d18O)
num_bins_monthly = int(len(weighted_sum_HadCM_old_4PIC) / num_vars)
for var_idx, var_name in enumerate(var_names):
print(f"Results for variable: {var_name}")
for bin_idx in range(num_bins_monthly):
idx = var_idx * num_bins_monthly + bin_idx
if effective_weights_total_HadCM_old_4PIC[idx] is not None and effective_weights_total_HadCM_old_4PIC[idx] != 0:
mu_likelihood[idx] = weighted_sum_HadCM_old_4PIC[idx] / effective_weights_total_HadCM_old_4PIC[idx]
std_likelihood[idx] = np.sqrt(1 / effective_weights_total_HadCM_old_4PIC[idx])
else:
# If there are no data points for this bin, set the likelihood to NaN
mu_likelihood[idx] = np.nan
std_likelihood[idx] = np.nan
print(f" Bin {bin_idx + 1}:")
print(f" Weighted Average: {mu_likelihood[idx]}")
print(f" Aggregated Uncertainty: {std_likelihood[idx]}")
print(f" Number of Data Points: {n_update_HadCM_old_4PIC[idx]}")
print()
print("Original Prior Mean SST-D47 monthly:\n", mu_prior_HadCM_old_4PIC_SST_D47_monthly_original)
print("Original Prior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_old_4PIC_SST_D47_monthly_original)))
print("Updated Posterior Mean SST-D47 monthly:\n", mu_post_HadCM_old_4PIC_SST_D47)
print("Updated Posterior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_post_HadCM_old_4PIC_SST_D47)))
print("Original Prior Mean SAT-D47 monthly:\n", mu_prior_HadCM_old_4PIC_SAT_monthly_original)
print("Original Prior Standard Deviation SAT-D47 monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_old_4PIC_SAT_monthly_original)))
print("Updated Posterior Mean SAT-D47 monthly:\n", mu_post_HadCM_old_4PIC_SAT_D47)
print("Updated Posterior Standard Deviation SAT-D47 monthly:\n", np.sqrt(np.diag(cov_post_HadCM_old_4PIC_SAT_D47)))
print("Original Prior Mean d18Oc monthly:\n", mu_prior_HadCM_old_4PIC_d18Oc_monthly_original)
print("Original Prior Standard Deviation d18Oc monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_old_4PIC_d18Oc_monthly_original)))
print("Updated Posterior Mean d18Oc monthly:\n", mu_post_HadCM_old_4PIC_d18Oc)
print("Updated Posterior Standard Deviation d18Oc monthly:\n", np.sqrt(np.diag(cov_post_HadCM_old_4PIC_d18Oc)))
print("Original Prior Mean precipitation monthly:\n", mu_prior_HadCM_old_4PIC_precip_monthly_original)
print("Original Prior Standard Deviation precipitation monthly:\n", np.sqrt(np.diag(cov_prior_HadCM_old_4PIC_precip_monthly_original)))
print("Updated Posterior Mean precipitation monthly:\n", mu_post_HadCM_old_4PIC_precip)
print("Updated Posterior Standard Deviation precipitation monthly:\n", np.sqrt(np.diag(cov_post_HadCM_old_4PIC_precip)))
Likelihood statistics:
Results for variable: D47_mean
Bin 1:
Weighted Average: 0.6315000000000001
Aggregated Uncertainty: 0.0145
Number of Data Points: 1.0
Bin 2:
Weighted Average: 0.5964285714285714
Aggregated Uncertainty: 0.01096096971726759
Number of Data Points: 1.0
Bin 3:
Weighted Average: 0.6065
Aggregated Uncertainty: 0.010253048327204941
Number of Data Points: 1.0
Bin 4:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 5:
Weighted Average: 0.5749687499999999
Aggregated Uncertainty: 0.0051265241636024705
Number of Data Points: 1.0
Bin 6:
Weighted Average: 0.5925625
Aggregated Uncertainty: 0.00725
Number of Data Points: 1.0
Bin 7:
Weighted Average: 0.5888260869565218
Aggregated Uncertainty: 0.004275816728492018
Number of Data Points: 1.0
Bin 8:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 9:
Weighted Average: 0.5830000000000001
Aggregated Uncertainty: 0.004973458969132757
Number of Data Points: 1.0
Bin 10:
Weighted Average: nan
Aggregated Uncertainty: nan
Number of Data Points: 0.0
Bin 11:
Weighted Average: 0.594
Aggregated Uncertainty: 0.011839200423452026
Number of Data Points: 1.0
Bin 12:
Weighted Average: 0.5921333333333333
Aggregated Uncertainty: 0.007487767802667672
Number of Data Points: 1.0
Results for variable: d18O
Bin 1:
Weighted Average: 0.016000000000000014
Aggregated Uncertainty: 0.0447213595499958
Number of Data Points: 1.0
Bin 2:
Weighted Average: 0.10700000000000001
Aggregated Uncertainty: 0.0316227766016838
Number of Data Points: 1.0
Bin 3:
Weighted Average: -0.22615384615384615
Aggregated Uncertainty: 0.02773500981126146
Number of Data Points: 1.0
Bin 4:
Weighted Average: -0.5469999999999999
Aggregated Uncertainty: 0.01414213562373095
Number of Data Points: 1.0
Bin 5:
Weighted Average: -1.2017647058823526
Aggregated Uncertainty: 0.009166984970282115
Number of Data Points: 1.0
Bin 6:
Weighted Average: -1.6498290598290601
Aggregated Uncertainty: 0.009245003270420488
Number of Data Points: 1.0
Bin 7:
Weighted Average: -2.0610810810810816
Aggregated Uncertainty: 0.009491579957524992
Number of Data Points: 1.0
Bin 8:
Weighted Average: -1.7621904761904763
Aggregated Uncertainty: 0.009759000729485335
Number of Data Points: 1.0
Bin 9:
Weighted Average: -1.3562711864406782
Aggregated Uncertainty: 0.009205746178983237
Number of Data Points: 1.0
Bin 10:
Weighted Average: -0.5620833333333334
Aggregated Uncertainty: 0.014433756729740647
Number of Data Points: 1.0
Bin 11:
Weighted Average: -0.06419354838709676
Aggregated Uncertainty: 0.017960530202677495
Number of Data Points: 1.0
Bin 12:
Weighted Average: -0.162
Aggregated Uncertainty: 0.0223606797749979
Number of Data Points: 1.0
Original Prior Mean SST-D47 monthly:
[0.60952059 0.61177987 0.61211207 0.60890818 0.59999147 0.58762014
0.57910703 0.57497457 0.5767857 0.58612855 0.59672445 0.60499141]
Original Prior Standard Deviation SST-D47 monthly:
[0.00730275 0.00751657 0.00756292 0.00688203 0.00519937 0.00330025
0.00165647 0.00170597 0.00223992 0.00457919 0.0061014 0.00687984]
Updated Posterior Mean SST-D47 monthly:
[0.60929279 0.61110217 0.61146843 0.60890818 0.60132146 0.59679646
0.5913868 0.57497457 0.570493 0.58612855 0.59963663 0.60529398]
Updated Posterior Standard Deviation SST-D47 monthly:
[4.06383364e-04 3.17817205e-04 2.03849021e-04 3.29272254e-10
3.16315655e-04 7.34458148e-04 6.69732097e-04 nan
3.03903741e-04 3.86105942e-10 2.61070761e-04 4.46781687e-04]
Original Prior Mean SAT-D47 monthly:
[17.37342478 17.21628214 17.78856557 19.24039866 22.18971914 26.23706462
29.33261007 30.70993194 29.73895416 26.07219594 21.69050496 18.52393239]
Original Prior Standard Deviation SAT-D47 monthly:
[3.2114442 2.69102368 2.25082291 1.96523166 1.63807297 1.35401718
0.73510388 0.49971448 0.91035189 1.98977278 2.90543435 3.37134836]
Updated Posterior Mean SAT-D47 monthly:
[0.59961509 0.59806084 0.59560856 0.59335018 0.58767151 0.57412668
0.56915225 0.57456599 0.5788128 0.58115739 0.59084795 0.59835057]
Updated Posterior Standard Deviation SAT-D47 monthly:
[0.00141255 0.00136087 0.00132509 0.0012541 0.00116415 0.0010171
0.00093373 0.00091888 0.00085299 0.00101592 0.00124689 0.001419 ]
Original Prior Mean d18Oc monthly:
[ 2.610453 2.78266516 2.80531485 2.55561563 1.87962861 0.93728201
0.28135718 -0.03614475 0.1034491 0.83319401 1.64799416 2.27215511]
Original Prior Standard Deviation d18Oc monthly:
[0.36157545 0.37407513 0.37312685 0.32006347 0.21320302 0.15150899
0.19818414 0.24130267 0.10970853 0.19072319 0.29013312 0.33416273]
Updated Posterior Mean d18Oc monthly:
[ 0.10466442 0.18408074 0.15635633 0.02406903 -0.41678584 -1.41772702
-1.76512541 -1.35428154 -1.1531825 -1.12463334 -0.6287255 -0.13126015]
Updated Posterior Standard Deviation d18Oc monthly:
[0.04366004 0.04294683 0.04246724 0.04064485 0.04176134 0.05359773
0.05593455 0.05003228 0.03412996 0.03322553 0.0375173 0.04319486]
Original Prior Mean precipitation monthly:
[4.51414761 2.96477545 2.0466914 1.70405398 1.499306 0.98548384
1.2141631 1.94227658 3.96484522 4.89490475 5.10539876 4.79175341]
Original Prior Standard Deviation precipitation monthly:
[0.54851291 0.54980863 0.52847315 0.61988324 0.67752496 0.34351868
0.40517783 0.93230212 0.90520864 0.74675508 0.64169083 0.55874858]
Updated Posterior Mean precipitation monthly:
[ 5.78186312 2.53759874 2.42827759 3.3392642 4.79783349 3.08769232
-0.2446832 -1.10487115 5.96112349 8.00533232 2.18892769 5.62862659]
Updated Posterior Standard Deviation precipitation monthly:
[0.36594123 0.20462568 0.19978116 0.24788844 0.32308452 0.17565873
0.28027528 0.46830502 0.61994237 0.63269722 0.43719639 0.40715268]
C:\Users\nwi213\AppData\Local\Temp\ipykernel_4724\1681332670.py:74: RuntimeWarning: invalid value encountered in sqrt
print("Updated Posterior Standard Deviation SST-D47 monthly:\n", np.sqrt(np.diag(cov_post_HadCM_old_4PIC_SST_D47)))
Plot monthly posteriors in D47 and d18Oc domain for both 2x and 4x preindustrial pCO2 scenarios¶
Start by calculating standard deviations and number of updates for different model scenarios¶
In [72]:
std_post_CESM_4PIC_SST_D47 = np.sqrt(np.diag(cov_post_CESM_4PIC_SST_D47))
std_post_CESM_2PIC_SST_D47 = np.sqrt(np.diag(cov_post_CESM_2PIC_SST_D47))
std_post_HadCM_new_1PIC_SST_D47 = np.sqrt(np.diag(cov_post_HadCM_new_1PIC_SST_D47))
std_post_HadCM_new_2PIC_SST_D47 = np.sqrt(np.diag(cov_post_HadCM_new_2PIC_SST_D47))
std_post_HadCM_new_1056ppm_SST_D47 = np.sqrt(np.diag(cov_post_HadCM_new_1056ppm_SST_D47))
std_post_HadCM_old_2PIC_SST_D47 = np.sqrt(np.diag(cov_post_HadCM_old_2PIC_SST_D47))
std_post_HadCM_old_4PIC_SST_D47 = np.sqrt(np.diag(cov_post_HadCM_old_4PIC_SST_D47))
std_post_CESM_4PIC_d18Oc = np.sqrt(np.diag(cov_post_CESM_4PIC_d18Oc))
std_post_CESM_2PIC_d18Oc = np.sqrt(np.diag(cov_post_CESM_2PIC_d18Oc))
std_post_HadCM_new_1PIC_d18Oc = np.sqrt(np.diag(cov_post_HadCM_new_1PIC_d18Oc))
std_post_HadCM_new_2PIC_d18Oc = np.sqrt(np.diag(cov_post_HadCM_new_2PIC_d18Oc))
std_post_HadCM_new_1056ppm_d18Oc = np.sqrt(np.diag(cov_post_HadCM_new_1056ppm_d18Oc))
std_post_HadCM_old_2PIC_d18Oc = np.sqrt(np.diag(cov_post_HadCM_old_2PIC_d18Oc))
std_post_HadCM_old_4PIC_d18Oc = np.sqrt(np.diag(cov_post_HadCM_old_4PIC_d18Oc))
std_prior_CESM_4PIC_SST_D47_monthly_original = np.sqrt(np.diag(cov_prior_CESM_4PIC_SST_D47_monthly_original))
std_prior_CESM_2PIC_SST_D47_monthly_original = np.sqrt(np.diag(cov_prior_CESM_2PIC_SST_D47_monthly_original))
std_prior_HadCM_new_1PIC_SST_D47_monthly_original = np.sqrt(np.diag(cov_prior_HadCM_new_1PIC_SST_D47_monthly_original))
std_prior_HadCM_new_2PIC_SST_D47_monthly_original = np.sqrt(np.diag(cov_prior_HadCM_new_2PIC_SST_D47_monthly_original))
std_prior_HadCM_new_1056ppm_SST_D47_monthly_original = np.sqrt(np.diag(cov_prior_HadCM_new_1056ppm_SST_D47_monthly_original))
std_prior_HadCM_old_2PIC_SST_D47_monthly_original = np.sqrt(np.diag(cov_prior_HadCM_old_2PIC_SST_D47_monthly_original))
std_prior_HadCM_old_4PIC_SST_D47_monthly_original = np.sqrt(np.diag(cov_prior_HadCM_old_4PIC_SST_D47_monthly_original))
std_prior_CESM_4PIC_d18Oc_monthly_original = np.sqrt(np.diag(cov_prior_CESM_4PIC_d18Oc_monthly_original))
std_prior_CESM_2PIC_d18Oc_monthly_original = np.sqrt(np.diag(cov_prior_CESM_2PIC_d18Oc_monthly_original))
std_prior_HadCM_new_1PIC_d18Oc_monthly_original = np.sqrt(np.diag(cov_prior_HadCM_new_1PIC_d18Oc_monthly_original))
std_prior_HadCM_new_2PIC_d18Oc_monthly_original = np.sqrt(np.diag(cov_prior_HadCM_new_2PIC_d18Oc_monthly_original))
std_prior_HadCM_new_1056ppm_d18Oc_monthly_original = np.sqrt(np.diag(cov_prior_HadCM_new_1056ppm_d18Oc_monthly_original))
std_prior_HadCM_old_2PIC_d18Oc_monthly_original = np.sqrt(np.diag(cov_prior_HadCM_old_2PIC_d18Oc_monthly_original))
std_prior_HadCM_old_4PIC_d18Oc_monthly_original = np.sqrt(np.diag(cov_prior_HadCM_old_4PIC_d18Oc_monthly_original))
var_start_D47_monthly = var_names.index("D47_mean") * num_bins_monthly # Determine the start index for the D47 variable
var_end_D47_monthly = var_start_D47_monthly + num_bins_monthly # Determine the end index for the D47 variable
var_start_d18Oc_monthly = var_names.index("d18O") * num_bins_monthly # Determine the start index for the d18Oc variable
var_end_d18Oc_monthly = var_start_d18Oc_monthly + num_bins_monthly # Determine the end index for the d18Oc variable
n_update_CESM_4PIC_D47 = n_update_CESM_4PIC[var_start_D47_monthly:var_end_D47_monthly] # Extract the number of updates for D47
n_update_CESM_2PIC_D47 = n_update_CESM_2PIC[var_start_D47_monthly:var_end_D47_monthly] # Extract the number of updates for D47
n_update_HadCM_new_1PIC_D47 = n_update_HadCM_new_1PIC[var_start_D47_monthly:var_end_D47_monthly] # Extract the number of updates for D47
n_update_HadCM_new_2PIC_D47 = n_update_HadCM_new_2PIC[var_start_D47_monthly:var_end_D47_monthly] # Extract the number of updates for D47
n_update_HadCM_new_1056ppm_D47 = n_update_HadCM_new_1056ppm[var_start_D47_monthly:var_end_D47_monthly] # Extract the number of updates for D47
n_update_HadCM_old_2PIC_D47 = n_update_HadCM_old_2PIC[var_start_D47_monthly:var_end_D47_monthly] # Extract the number of updates for D47
n_update_HadCM_old_4PIC_D47 = n_update_HadCM_old_4PIC[var_start_D47_monthly:var_end_D47_monthly] # Extract the number of updates for D47
n_update_CESM_4PIC_d18Oc = n_update_CESM_4PIC[var_start_d18Oc_monthly:var_end_d18Oc_monthly] # Extract the number of updates for d18Oc
n_update_CESM_2PIC_d18Oc = n_update_CESM_2PIC[var_start_d18Oc_monthly:var_end_d18Oc_monthly] # Extract the number of updates for d18Oc
n_update_HadCM_new_1PIC_d18Oc = n_update_HadCM_new_1PIC[var_start_d18Oc_monthly:var_end_d18Oc_monthly] # Extract the number of updates for d18Oc
n_update_HadCM_new_2PIC_d18Oc = n_update_HadCM_new_2PIC[var_start_d18Oc_monthly:var_end_d18Oc_monthly] # Extract the number of updates for d18Oc
n_update_HadCM_new_1056ppm_d18Oc = n_update_HadCM_new_1056ppm[var_start_d18Oc_monthly:var_end_d18Oc_monthly] # Extract the number of updates for d18Oc
n_update_HadCM_old_2PIC_d18Oc = n_update_HadCM_old_2PIC[var_start_d18Oc_monthly:var_end_d18Oc_monthly] # Extract the number of updates for d18Oc
n_update_HadCM_old_4PIC_d18Oc = n_update_HadCM_old_4PIC[var_start_d18Oc_monthly:var_end_d18Oc_monthly] # Extract the number of updates for d18Oc
C:\Users\nwi213\AppData\Local\Temp\ipykernel_4724\2373763780.py:4: RuntimeWarning: invalid value encountered in sqrt std_post_HadCM_new_2PIC_SST_D47 = np.sqrt(np.diag(cov_post_HadCM_new_2PIC_SST_D47)) C:\Users\nwi213\AppData\Local\Temp\ipykernel_4724\2373763780.py:6: RuntimeWarning: invalid value encountered in sqrt std_post_HadCM_old_2PIC_SST_D47 = np.sqrt(np.diag(cov_post_HadCM_old_2PIC_SST_D47)) C:\Users\nwi213\AppData\Local\Temp\ipykernel_4724\2373763780.py:7: RuntimeWarning: invalid value encountered in sqrt std_post_HadCM_old_4PIC_SST_D47 = np.sqrt(np.diag(cov_post_HadCM_old_4PIC_SST_D47))
Then plot all priors and posteriors for d18Oc and D47¶
In [73]:
# Initialize subplots for monthly results
fig, axs = plt.subplots(2, 7, figsize=(20, 8), sharex = "col", sharey="row")
# Plot monthly results for each model and variable
# --- CESM 4x preindustrial pCO2 scenario ---
# --- D47 ---
# PRIOR
axs[0, 0].plot(months_scale, mu_prior_CESM_4PIC_SST_D47_monthly_original, label='Prior Mean', color='b', marker='o')
axs[0, 0].fill_between(
months_scale,
mu_prior_CESM_4PIC_SST_D47_monthly_original - stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SST_D47_monthly_original / np.sqrt(n_models_CESM_4PIC_monthly),
mu_prior_CESM_4PIC_SST_D47_monthly_original + stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SST_D47_monthly_original / np.sqrt(n_models_CESM_4PIC_monthly),
color='b',
alpha=0.2,
label='95% Confidence Interval'
)
# LIKELIHOOD
# Determine the start and end indices for the selected variable to parse information from the likelihood statistics
axs[0, 0].plot(months_scale, mu_likelihood[var_start_D47_monthly:var_end_D47_monthly], label='Likelihood Mean', color='y', marker='o')
axs[0, 0].fill_between(
months_scale,
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] - stats.t.ppf(1 - 0.025, n_update_CESM_4PIC_D47) * std_likelihood[var_start_D47_monthly:var_end_D47_monthly] / np.sqrt(n_update_CESM_4PIC_D47),
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] + stats.t.ppf(1 - 0.025, n_update_CESM_4PIC_D47) * std_likelihood[var_start_D47_monthly:var_end_D47_monthly] / np.sqrt(n_update_CESM_4PIC_D47),
color='y',
alpha=0.2,
label='95% Confidence Interval'
)
for measurement in Lutetian_data_monthly_aggregated_dict:
axs[0, 0].plot(measurement["month_score"] + 1, measurement["D47_mean"], color="y", marker="o", alpha=0.2)
axs[0, 0].errorbar(measurement["month_score"] + 1, measurement["D47_mean"], yerr=measurement["D47_SD"], color="y", alpha=0.2, capsize=5)
# POSTERIOR
axs[0, 0].plot(months_scale, mu_post_CESM_4PIC_SST_D47, label='Posterior Mean', color='r', marker='o')
axs[0, 0].fill_between(
months_scale,
mu_post_CESM_4PIC_SST_D47 - stats.t.ppf(1 - 0.025, (n_update_CESM_4PIC_D47 + n_models_CESM_4PIC_monthly)) * std_post_CESM_4PIC_SST_D47 / np.sqrt(n_update_CESM_4PIC_D47 + n_models_CESM_4PIC_monthly),
mu_post_CESM_4PIC_SST_D47 + stats.t.ppf(1 - 0.025, (n_update_CESM_4PIC_D47 + n_models_CESM_4PIC_monthly)) * std_post_CESM_4PIC_SST_D47 / np.sqrt(n_update_CESM_4PIC_D47 + n_models_CESM_4PIC_monthly),
color='r',
alpha=0.2,
label='95% Confidence Interval (Posterior)'
)
# Formatting
axs[0, 0].set_xticks(months_scale, month_names)
axs[0, 0].set_title('CESM\n4x preindustrial pCO2')
axs[0, 0].set_xlabel('Month')
axs[0, 0].set_ylabel('SST D47 value')
axs[0, 0].set_ylim(0.55, 0.65)
# axs[0, 0].legend()
axs[0, 0].grid(True)
# ---d18Oc---
# PRIOR
axs[1, 0].plot(months_scale, mu_prior_CESM_4PIC_d18Oc_monthly_original, label='Prior Mean', color='b', marker='o')
axs[1, 0].fill_between(
months_scale,
mu_prior_CESM_4PIC_d18Oc_monthly_original - stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_d18Oc_monthly_original / np.sqrt(n_models_CESM_4PIC_monthly),
mu_prior_CESM_4PIC_d18Oc_monthly_original + stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_d18Oc_monthly_original / np.sqrt(n_models_CESM_4PIC_monthly),
color='b',
alpha=0.2,
label='95% Confidence Interval'
)
# LIKELIHOOD
# Determine the start and end indices for the selected variable
axs[1, 0].plot(months_scale, mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly], label='Likelihood Mean', color='y', marker='o')
axs[1, 0].fill_between(
months_scale,
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] - stats.t.ppf(1 - 0.025, n_update_CESM_4PIC_d18Oc) * std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] / np.sqrt(n_update_CESM_4PIC_d18Oc),
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] + stats.t.ppf(1 - 0.025, n_update_CESM_4PIC_d18Oc) * std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] / np.sqrt(n_update_CESM_4PIC_d18Oc),
color='y',
alpha=0.2,
label='95% Confidence Interval'
)
for measurement in Lutetian_data_monthly_aggregated_dict:
axs[1, 0].plot(measurement["month_score"] + 1, measurement["d18O"], color="y", marker="o", alpha=0.2)
axs[1, 0].errorbar(measurement["month_score"] + 1, measurement["d18O"], yerr=measurement["d18O_SD"], color="y", alpha=0.2, capsize=5)
# POSTERIOR
axs[1, 0].plot(months_scale, mu_post_CESM_4PIC_d18Oc, label='Posterior Mean', color='r', marker='o')
axs[1, 0].fill_between(
months_scale,
mu_post_CESM_4PIC_d18Oc - stats.t.ppf(1 - 0.025, (n_update_CESM_4PIC_d18Oc + n_models_CESM_4PIC_monthly)) * std_post_CESM_4PIC_d18Oc / np.sqrt(n_update_CESM_4PIC_d18Oc + n_models_CESM_4PIC_monthly),
mu_post_CESM_4PIC_d18Oc + stats.t.ppf(1 - 0.025, (n_update_CESM_4PIC_d18Oc + n_models_CESM_4PIC_monthly)) * std_post_CESM_4PIC_d18Oc / np.sqrt(n_update_CESM_4PIC_d18Oc + n_models_CESM_4PIC_monthly),
color='r',
alpha=0.2,
label='95% Confidence Interval (Posterior)'
)
# Formatting
axs[1, 0].set_xticks(months_scale, month_names, rotation=45, ha='right')
axs[1, 0].set_xlabel('Month')
axs[1, 0].set_ylabel('d18Oc value')
# axs[1, 0].legend()
axs[1, 0].grid(True)
# --- CESM 2x preindustrial pCO2 scenario ---
# --- D47 ---
# PRIOR
axs[0, 1].plot(months_scale, mu_prior_CESM_2PIC_SST_D47_monthly_original, label='Prior Mean', color='b', marker='o')
axs[0, 1].fill_between(
months_scale,
mu_prior_CESM_2PIC_SST_D47_monthly_original - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SST_D47_monthly_original / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_SST_D47_monthly_original + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SST_D47_monthly_original / np.sqrt(n_models_CESM_2PIC_monthly),
color='b',
alpha=0.2,
label='95% Confidence Interval'
)
# LIKELIHOOD
axs[0, 1].plot(months_scale, mu_likelihood[var_start_D47_monthly:var_end_D47_monthly], label='Likelihood Mean', color='y', marker='o')
axs[0, 1].fill_between(
months_scale,
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] - stats.t.ppf(1 - 0.025, n_update_CESM_2PIC_D47) * std_likelihood[var_start_D47_monthly:var_end_D47_monthly] / np.sqrt(n_update_CESM_2PIC_D47),
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] + stats.t.ppf(1 - 0.025, n_update_CESM_2PIC_D47) * std_likelihood[var_start_D47_monthly:var_end_D47_monthly] / np.sqrt(n_update_CESM_2PIC_D47),
color='y',
alpha=0.2,
label='95% Confidence Interval'
)
# POSTERIOR
axs[0, 1].plot(months_scale, mu_post_CESM_2PIC_SST_D47, label='Posterior Mean', color='r', marker='o')
axs[0, 1].fill_between(
months_scale,
mu_post_CESM_2PIC_SST_D47 - stats.t.ppf(1 - 0.025, (n_update_CESM_2PIC_D47 + n_models_CESM_2PIC_monthly)) * std_post_CESM_2PIC_SST_D47 / np.sqrt(n_update_CESM_2PIC_D47 + n_models_CESM_2PIC_monthly),
mu_post_CESM_2PIC_SST_D47 + stats.t.ppf(1 - 0.025, (n_update_CESM_2PIC_D47 + n_models_CESM_2PIC_monthly)) * std_post_CESM_2PIC_SST_D47 / np.sqrt(n_update_CESM_2PIC_D47 + n_models_CESM_2PIC_monthly),
color='r',
alpha=0.2,
label='95% Confidence Interval (Posterior)'
)
# Formatting
axs[0, 1].set_xticks(months_scale, month_names)
axs[0, 1].set_title('CESM\n2x preindustrial pCO2')
axs[0, 1].set_xlabel('Month')
axs[0, 1].set_ylabel('SST D47 value')
# axs[0, 1].legend()
axs[0, 1].grid(True)
# ---d18Oc---
# PRIOR
axs[1, 1].plot(months_scale, mu_prior_CESM_2PIC_d18Oc_monthly_original, label='Prior Mean', color='b', marker='o')
axs[1, 1].fill_between(
months_scale,
mu_prior_CESM_2PIC_d18Oc_monthly_original - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_d18Oc_monthly_original / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_d18Oc_monthly_original + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_d18Oc_monthly_original / np.sqrt(n_models_CESM_2PIC_monthly),
color='b',
alpha=0.2,
label='95% Confidence Interval'
)
# LIKELIHOOD
axs[1, 1].plot(months_scale, mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly], label='Likelihood Mean', color='y', marker='o')
axs[1, 1].fill_between(
months_scale,
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] - stats.t.ppf(1 - 0.025, n_update_CESM_2PIC_d18Oc) * std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] / np.sqrt(n_update_CESM_2PIC_d18Oc),
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] + stats.t.ppf(1 - 0.025, n_update_CESM_2PIC_d18Oc) * std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] / np.sqrt(n_update_CESM_2PIC_d18Oc),
color='y',
alpha=0.2,
label='95% Confidence Interval'
)
# POSTERIOR
axs[1, 1].plot(months_scale, mu_post_CESM_2PIC_d18Oc, label='Posterior Mean', color='r', marker='o')
axs[1, 1].fill_between(
months_scale,
mu_post_CESM_2PIC_d18Oc - stats.t.ppf(1 - 0.025, (n_update_CESM_2PIC_d18Oc + n_models_CESM_2PIC_monthly)) * std_post_CESM_2PIC_d18Oc / np.sqrt(n_update_CESM_2PIC_d18Oc + n_models_CESM_2PIC_monthly),
mu_post_CESM_2PIC_d18Oc + stats.t.ppf(1 - 0.025, (n_update_CESM_2PIC_d18Oc + n_models_CESM_2PIC_monthly)) * std_post_CESM_2PIC_d18Oc / np.sqrt(n_update_CESM_2PIC_d18Oc + n_models_CESM_2PIC_monthly),
color='r',
alpha=0.2,
label='95% Confidence Interval (Posterior)'
)
# Formatting
axs[1, 1].set_xticks(months_scale, month_names, rotation=45, ha='right')
axs[1, 1].set_xlabel('Month')
axs[1, 1].set_ylabel('d18Oc value')
# axs[1, 1].legend()
axs[1, 1].grid(True)
# --- HadCM (new) 1x preindustrial pCO2 scenario ---
# --- D47 ---
# PRIOR
axs[0, 2].plot(months_scale, mu_prior_HadCM_new_1PIC_SST_D47_monthly_original, label='Prior Mean', color='b', marker='o')
axs[0, 2].fill_between(
months_scale,
mu_prior_HadCM_new_1PIC_SST_D47_monthly_original - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SST_D47_monthly_original / np.sqrt(n_models_HadCM_new_1PIC_monthly),
mu_prior_HadCM_new_1PIC_SST_D47_monthly_original + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SST_D47_monthly_original / np.sqrt(n_models_HadCM_new_1PIC_monthly),
color='b',
alpha=0.2,
label='95% Confidence Interval'
)
# LIKELIHOOD
axs[0, 2].plot(months_scale, mu_likelihood[var_start_D47_monthly:var_end_D47_monthly], label='Likelihood Mean', color='y', marker='o')
axs[0, 2].fill_between(
months_scale,
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] - stats.t.ppf(1 - 0.025, n_update_HadCM_new_1PIC_D47) * std_likelihood[var_start_D47_monthly:var_end_D47_monthly] / np.sqrt(n_update_HadCM_new_1PIC_D47),
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] + stats.t.ppf(1 - 0.025, n_update_HadCM_new_1PIC_D47) * std_likelihood[var_start_D47_monthly:var_end_D47_monthly] / np.sqrt(n_update_HadCM_new_1PIC_D47),
color='y',
alpha=0.2,
label='95% Confidence Interval'
)
# POSTERIOR
axs[0, 2].plot(months_scale, mu_post_HadCM_new_1PIC_SST_D47, label='Posterior Mean', color='r', marker='o')
axs[0, 2].fill_between(
months_scale,
mu_post_HadCM_new_1PIC_SST_D47 - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1PIC_D47 + n_models_HadCM_new_1PIC_monthly)) * std_post_HadCM_new_1PIC_SST_D47 / np.sqrt(n_update_HadCM_new_1PIC_D47 + n_models_HadCM_new_1PIC_monthly),
mu_post_HadCM_new_1PIC_SST_D47 + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1PIC_D47 + n_models_HadCM_new_1PIC_monthly)) * std_post_HadCM_new_1PIC_SST_D47 / np.sqrt(n_update_HadCM_new_1PIC_D47 + n_models_HadCM_new_1PIC_monthly),
color='r',
alpha=0.2,
label='95% Confidence Interval (Posterior)'
)
# Formatting
axs[0, 2].set_xticks(months_scale, month_names)
axs[0, 2].set_title('HadCM\n1x preindustrial pCO2')
axs[0, 2].set_xlabel('Month')
axs[0, 2].set_ylabel('SST D47 value')
# axs[0, 2].legend()
axs[0, 2].grid(True)
# ---d18Oc---
# PRIOR
axs[1, 2].plot(months_scale, mu_prior_HadCM_new_1PIC_d18Oc_monthly_original, label='Prior Mean', color='b', marker='o')
axs[1, 2].fill_between(
months_scale,
mu_prior_HadCM_new_1PIC_d18Oc_monthly_original - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_d18Oc_monthly_original / np.sqrt(n_models_HadCM_new_1PIC_monthly),
mu_prior_HadCM_new_1PIC_d18Oc_monthly_original + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_d18Oc_monthly_original / np.sqrt(n_models_HadCM_new_1PIC_monthly),
color='b',
alpha=0.2,
label='95% Confidence Interval'
)
# LIKELIHOOD
axs[1, 2].plot(months_scale, mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly], label='Likelihood Mean', color='y', marker='o')
axs[1, 2].fill_between(
months_scale,
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] - stats.t.ppf(1 - 0.025, n_update_HadCM_new_1PIC_d18Oc) * std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] / np.sqrt(n_update_HadCM_new_1PIC_d18Oc),
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] + stats.t.ppf(1 - 0.025, n_update_HadCM_new_1PIC_d18Oc) * std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] / np.sqrt(n_update_HadCM_new_1PIC_d18Oc),
color='y',
alpha=0.2,
label='95% Confidence Interval'
)
# POSTERIOR
axs[1, 2].plot(months_scale, mu_post_HadCM_new_1PIC_d18Oc, label='Posterior Mean', color='r', marker='o')
axs[1, 2].fill_between(
months_scale,
mu_post_HadCM_new_1PIC_d18Oc - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1PIC_d18Oc + n_models_HadCM_new_1PIC_monthly)) * std_post_HadCM_new_1PIC_d18Oc / np.sqrt(n_update_HadCM_new_1PIC_d18Oc + n_models_HadCM_new_1PIC_monthly),
mu_post_HadCM_new_1PIC_d18Oc + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1PIC_d18Oc + n_models_HadCM_new_1PIC_monthly)) * std_post_HadCM_new_1PIC_d18Oc / np.sqrt(n_update_HadCM_new_1PIC_d18Oc + n_models_HadCM_new_1PIC_monthly),
color='r',
alpha=0.2,
label='95% Confidence Interval (Posterior)'
)
# Formatting
axs[1, 2].set_xticks(months_scale, month_names, rotation=45, ha='right')
axs[1, 2].set_xlabel('Month')
axs[1, 2].set_ylabel('d18Oc value')
# axs[1, 2].legend()
axs[1, 2].grid(True)
# --- HadCM (new) 2x preindustrial pCO2 scenario ---
# --- D47 ---
# PRIOR
axs[0, 3].plot(months_scale, mu_prior_HadCM_new_2PIC_SST_D47_monthly_original, label='Prior Mean', color='b', marker='o')
axs[0, 3].fill_between(
months_scale,
mu_prior_HadCM_new_2PIC_SST_D47_monthly_original - stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SST_D47_monthly_original / np.sqrt(n_models_HadCM_new_2PIC_monthly),
mu_prior_HadCM_new_2PIC_SST_D47_monthly_original + stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SST_D47_monthly_original / np.sqrt(n_models_HadCM_new_2PIC_monthly),
color='b',
alpha=0.2,
label='95% Confidence Interval'
)
# LIKELIHOOD
axs[0, 3].plot(months_scale, mu_likelihood[var_start_D47_monthly:var_end_D47_monthly], label='Likelihood Mean', color='y', marker='o')
axs[0, 3].fill_between(
months_scale,
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] - stats.t.ppf(1 - 0.025, n_update_HadCM_new_2PIC_D47) * std_likelihood[var_start_D47_monthly:var_end_D47_monthly] / np.sqrt(n_update_HadCM_new_2PIC_D47),
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] + stats.t.ppf(1 - 0.025, n_update_HadCM_new_2PIC_D47) * std_likelihood[var_start_D47_monthly:var_end_D47_monthly] / np.sqrt(n_update_HadCM_new_2PIC_D47),
color='y',
alpha=0.2,
label='95% Confidence Interval'
)
# POSTERIOR
axs[0, 3].plot(months_scale, mu_post_HadCM_new_2PIC_SST_D47, label='Posterior Mean', color='r', marker='o')
axs[0, 3].fill_between(
months_scale,
mu_post_HadCM_new_2PIC_SST_D47 - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_2PIC_D47 + n_models_HadCM_new_2PIC_monthly)) * std_post_HadCM_new_2PIC_SST_D47 / np.sqrt(n_update_HadCM_new_2PIC_D47 + n_models_HadCM_new_2PIC_monthly),
mu_post_HadCM_new_2PIC_SST_D47 + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_2PIC_D47 + n_models_HadCM_new_2PIC_monthly)) * std_post_HadCM_new_2PIC_SST_D47 / np.sqrt(n_update_HadCM_new_2PIC_D47 + n_models_HadCM_new_2PIC_monthly),
color='r',
alpha=0.2,
label='95% Confidence Interval (Posterior)'
)
# Formatting
axs[0, 3].set_xticks(months_scale, month_names)
axs[0, 3].set_title('HadCM\n2x preindustrial pCO2')
axs[0, 3].set_xlabel('Month')
axs[0, 3].set_ylabel('SST D47 value')
# axs[0, 3].legend()
axs[0, 3].grid(True)
# ---d18Oc---
# PRIOR
axs[1, 3].plot(months_scale, mu_prior_HadCM_new_2PIC_d18Oc_monthly_original, label='Prior Mean', color='b', marker='o')
axs[1, 3].fill_between(
months_scale,
mu_prior_HadCM_new_2PIC_d18Oc_monthly_original - stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_d18Oc_monthly_original / np.sqrt(n_models_HadCM_new_2PIC_monthly),
mu_prior_HadCM_new_2PIC_d18Oc_monthly_original + stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_d18Oc_monthly_original / np.sqrt(n_models_HadCM_new_2PIC_monthly),
color='b',
alpha=0.2,
label='95% Confidence Interval'
)
# LIKELIHOOD
axs[1, 3].plot(months_scale, mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly], label='Likelihood Mean', color='y', marker='o')
axs[1, 3].fill_between(
months_scale,
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] - stats.t.ppf(1 - 0.025, n_update_HadCM_new_2PIC_d18Oc) * std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] / np.sqrt(n_update_HadCM_new_2PIC_d18Oc),
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] + stats.t.ppf(1 - 0.025, n_update_HadCM_new_2PIC_d18Oc) * std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] / np.sqrt(n_update_HadCM_new_2PIC_d18Oc),
color='y',
alpha=0.2,
label='95% Confidence Interval'
)
# POSTERIOR
axs[1, 3].plot(months_scale, mu_post_HadCM_new_2PIC_d18Oc, label='Posterior Mean', color='r', marker='o')
axs[1, 3].fill_between(
months_scale,
mu_post_HadCM_new_2PIC_d18Oc - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_2PIC_d18Oc + n_models_HadCM_new_2PIC_monthly)) * std_post_HadCM_new_2PIC_d18Oc / np.sqrt(n_update_HadCM_new_2PIC_d18Oc + n_models_HadCM_new_2PIC_monthly),
mu_post_HadCM_new_2PIC_d18Oc + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_2PIC_d18Oc + n_models_HadCM_new_2PIC_monthly)) * std_post_HadCM_new_2PIC_d18Oc / np.sqrt(n_update_HadCM_new_2PIC_d18Oc + n_models_HadCM_new_2PIC_monthly),
color='r',
alpha=0.2,
label='95% Confidence Interval (Posterior)'
)
# Formatting
axs[1, 3].set_xticks(months_scale, month_names, rotation=45, ha='right')
axs[1, 3].set_xlabel('Month')
axs[1, 3].set_ylabel('d18Oc value')
# axs[1, 3].legend()
axs[1, 3].grid(True)
# --- HadCM (new) 1056 ppm pCO2 scenario ---
# --- D47 ---
# PRIOR
axs[0, 4].plot(months_scale, mu_prior_HadCM_new_1056ppm_SST_D47_monthly_original, label='Prior Mean', color='b', marker='o')
axs[0, 4].fill_between(
months_scale,
mu_prior_HadCM_new_1056ppm_SST_D47_monthly_original - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SST_D47_monthly_original / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
mu_prior_HadCM_new_1056ppm_SST_D47_monthly_original + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SST_D47_monthly_original / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
color='b',
alpha=0.2,
label='95% Confidence Interval'
)
# LIKELIHOOD
axs[0, 4].plot(months_scale, mu_likelihood[var_start_D47_monthly:var_end_D47_monthly], label='Likelihood Mean', color='y', marker='o')
axs[0, 4].fill_between(
months_scale,
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] - stats.t.ppf(1 - 0.025, n_update_HadCM_new_1056ppm_D47) * std_likelihood[var_start_D47_monthly:var_end_D47_monthly] / np.sqrt(n_update_HadCM_new_1056ppm_D47),
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] + stats.t.ppf(1 - 0.025, n_update_HadCM_new_1056ppm_D47) * std_likelihood[var_start_D47_monthly:var_end_D47_monthly] / np.sqrt(n_update_HadCM_new_1056ppm_D47),
color='y',
alpha=0.2,
label='95% Confidence Interval'
)
# POSTERIOR
axs[0, 4].plot(months_scale, mu_post_HadCM_new_1056ppm_SST_D47, label='Posterior Mean', color='r', marker='o')
axs[0, 4].fill_between(
months_scale,
mu_post_HadCM_new_1056ppm_SST_D47 - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1056ppm_D47 + n_models_HadCM_new_1056ppm_monthly)) * std_post_HadCM_new_1056ppm_SST_D47 / np.sqrt(n_update_HadCM_new_1056ppm_D47 + n_models_HadCM_new_1056ppm_monthly),
mu_post_HadCM_new_1056ppm_SST_D47 + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1056ppm_D47 + n_models_HadCM_new_1056ppm_monthly)) * std_post_HadCM_new_1056ppm_SST_D47 / np.sqrt(n_update_HadCM_new_1056ppm_D47 + n_models_HadCM_new_1056ppm_monthly),
color='r',
alpha=0.2,
label='95% Confidence Interval (Posterior)'
)
# Formatting
axs[0, 4].set_xticks(months_scale, month_names)
axs[0, 4].set_title('HadCM\n1056 ppm pCO2')
axs[0, 4].set_xlabel('Month')
axs[0, 4].set_ylabel('SST D47 value')
# axs[0, 4].legend()
axs[0, 4].grid(True)
# ---d18Oc---
# PRIOR
axs[1, 4].plot(months_scale, mu_prior_HadCM_new_1056ppm_d18Oc_monthly_original, label='Prior Mean', color='b', marker='o')
axs[1, 4].fill_between(
months_scale,
mu_prior_HadCM_new_1056ppm_d18Oc_monthly_original - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_d18Oc_monthly_original / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
mu_prior_HadCM_new_1056ppm_d18Oc_monthly_original + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_d18Oc_monthly_original / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
color='b',
alpha=0.2,
label='95% Confidence Interval'
)
# LIKELIHOOD
axs[1, 4].plot(months_scale, mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly], label='Likelihood Mean', color='y', marker='o')
axs[1, 4].fill_between(
months_scale,
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] - stats.t.ppf(1 - 0.025, n_update_HadCM_new_1056ppm_d18Oc) * std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] / np.sqrt(n_update_HadCM_new_1056ppm_d18Oc),
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] + stats.t.ppf(1 - 0.025, n_update_HadCM_new_1056ppm_d18Oc) * std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] / np.sqrt(n_update_HadCM_new_1056ppm_d18Oc),
color='y',
alpha=0.2,
label='95% Confidence Interval'
)
# POSTERIOR
axs[1, 4].plot(months_scale, mu_post_HadCM_new_1056ppm_d18Oc, label='Posterior Mean', color='r', marker='o')
axs[1, 4].fill_between(
months_scale,
mu_post_HadCM_new_1056ppm_d18Oc - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1056ppm_d18Oc + n_models_HadCM_new_1056ppm_monthly)) * std_post_HadCM_new_1056ppm_d18Oc / np.sqrt(n_update_HadCM_new_1056ppm_d18Oc + n_models_HadCM_new_1056ppm_monthly),
mu_post_HadCM_new_1056ppm_d18Oc + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1056ppm_d18Oc + n_models_HadCM_new_1056ppm_monthly)) * std_post_HadCM_new_1056ppm_d18Oc / np.sqrt(n_update_HadCM_new_1056ppm_d18Oc + n_models_HadCM_new_1056ppm_monthly),
color='r',
alpha=0.2,
label='95% Confidence Interval (Posterior)'
)
# Formatting
axs[1, 4].set_xticks(months_scale, month_names, rotation=45, ha='right')
axs[1, 4].set_xlabel('Month')
axs[1, 4].set_ylabel('d18Oc value')
# axs[1, 4].legend()
axs[1, 4].grid(True)
# --- HadCM (old) 2x preindustrial pCO2 scenario ---
# --- D47 ---
# PRIOR
axs[0, 5].plot(months_scale, mu_prior_HadCM_old_2PIC_SST_D47_monthly_original, label='Prior Mean', color='b', marker='o')
axs[0, 5].fill_between(
months_scale,
mu_prior_HadCM_old_2PIC_SST_D47_monthly_original - stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SST_D47_monthly_original / np.sqrt(n_models_HadCM_old_2PIC_monthly),
mu_prior_HadCM_old_2PIC_SST_D47_monthly_original + stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SST_D47_monthly_original / np.sqrt(n_models_HadCM_old_2PIC_monthly),
color='b',
alpha=0.2,
label='95% Confidence Interval'
)
# LIKELIHOOD
axs[0, 5].plot(months_scale, mu_likelihood[var_start_D47_monthly:var_end_D47_monthly], label='Likelihood Mean', color='y', marker='o')
axs[0, 5].fill_between(
months_scale,
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] - stats.t.ppf(1 - 0.025, n_update_HadCM_old_2PIC_D47) * std_likelihood[var_start_D47_monthly:var_end_D47_monthly] / np.sqrt(n_update_HadCM_old_2PIC_D47),
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] + stats.t.ppf(1 - 0.025, n_update_HadCM_old_2PIC_D47) * std_likelihood[var_start_D47_monthly:var_end_D47_monthly] / np.sqrt(n_update_HadCM_old_2PIC_D47),
color='y',
alpha=0.2,
label='95% Confidence Interval'
)
# POSTERIOR
axs[0, 5].plot(months_scale, mu_post_HadCM_old_2PIC_SST_D47, label='Posterior Mean', color='r', marker='o')
axs[0, 5].fill_between(
months_scale,
mu_post_HadCM_old_2PIC_SST_D47 - stats.t.ppf(1 - 0.025, (n_update_HadCM_old_2PIC_D47 + n_models_HadCM_old_2PIC_monthly)) * std_post_HadCM_old_2PIC_SST_D47 / np.sqrt(n_update_HadCM_old_2PIC_D47 + n_models_HadCM_old_2PIC_monthly),
mu_post_HadCM_old_2PIC_SST_D47 + stats.t.ppf(1 - 0.025, (n_update_HadCM_old_2PIC_D47 + n_models_HadCM_old_2PIC_monthly)) * std_post_HadCM_old_2PIC_SST_D47 / np.sqrt(n_update_HadCM_old_2PIC_D47 + n_models_HadCM_old_2PIC_monthly),
color='r',
alpha=0.2,
label='95% Confidence Interval (Posterior)'
)
# Formatting
axs[0, 5].set_xticks(months_scale, month_names)
axs[0, 5].set_title('HadCM (old)\n2x preindustrial pCO2')
axs[0, 5].set_xlabel('Month')
axs[0, 5].set_ylabel('SST D47 value')
# axs[0, 5].legend()
axs[0, 5].grid(True)
# ---d18Oc---
# PRIOR
axs[1, 5].plot(months_scale, mu_prior_HadCM_old_2PIC_d18Oc_monthly_original, label='Prior Mean', color='b', marker='o')
axs[1, 5].fill_between(
months_scale,
mu_prior_HadCM_old_2PIC_d18Oc_monthly_original - stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_d18Oc_monthly_original / np.sqrt(n_models_HadCM_old_2PIC_monthly),
mu_prior_HadCM_old_2PIC_d18Oc_monthly_original + stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_d18Oc_monthly_original / np.sqrt(n_models_HadCM_old_2PIC_monthly),
color='b',
alpha=0.2,
label='95% Confidence Interval'
)
# LIKELIHOOD
axs[1, 5].plot(months_scale, mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly], label='Likelihood Mean', color='y', marker='o')
axs[1, 5].fill_between(
months_scale,
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] - stats.t.ppf(1 - 0.025, n_update_HadCM_old_2PIC_d18Oc) * std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] / np.sqrt(n_update_HadCM_old_2PIC_d18Oc),
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] + stats.t.ppf(1 - 0.025, n_update_HadCM_old_2PIC_d18Oc) * std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] / np.sqrt(n_update_HadCM_old_2PIC_d18Oc),
color='y',
alpha=0.2,
label='95% Confidence Interval'
)
# POSTERIOR
axs[1, 5].plot(months_scale, mu_post_HadCM_old_2PIC_d18Oc, label='Posterior Mean', color='r', marker='o')
axs[1, 5].fill_between(
months_scale,
mu_post_HadCM_old_2PIC_d18Oc - stats.t.ppf(1 - 0.025, (n_update_HadCM_old_2PIC_d18Oc + n_models_HadCM_old_2PIC_monthly)) * std_post_HadCM_old_2PIC_d18Oc / np.sqrt(n_update_HadCM_old_2PIC_d18Oc + n_models_HadCM_old_2PIC_monthly),
mu_post_HadCM_old_2PIC_d18Oc + stats.t.ppf(1 - 0.025, (n_update_HadCM_old_2PIC_d18Oc + n_models_HadCM_old_2PIC_monthly)) * std_post_HadCM_old_2PIC_d18Oc / np.sqrt(n_update_HadCM_old_2PIC_d18Oc + n_models_HadCM_old_2PIC_monthly),
color='r',
alpha=0.2,
label='95% Confidence Interval (Posterior)'
)
# Formatting
axs[1, 5].set_xticks(months_scale, month_names, rotation=45, ha='right')
axs[1, 5].set_xlabel('Month')
axs[1, 5].set_ylabel('d18Oc value')
# axs[1, 5].legend()
axs[1, 5].grid(True)
# --- HadCM (old) 4x preindustrial pCO2 scenario ---
# --- D47 ---
# PRIOR
axs[0, 6].plot(months_scale, mu_prior_HadCM_old_4PIC_SST_D47_monthly_original, label='Prior Mean', color='b', marker='o')
axs[0, 6].fill_between(
months_scale,
mu_prior_HadCM_old_4PIC_SST_D47_monthly_original - stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SST_D47_monthly_original / np.sqrt(n_models_HadCM_old_4PIC_monthly),
mu_prior_HadCM_old_4PIC_SST_D47_monthly_original + stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SST_D47_monthly_original / np.sqrt(n_models_HadCM_old_4PIC_monthly),
color='b',
alpha=0.2,
label='95% Confidence Interval'
)
# LIKELIHOOD
axs[0, 6].plot(months_scale, mu_likelihood[var_start_D47_monthly:var_end_D47_monthly], label='Likelihood Mean', color='y', marker='o')
axs[0, 6].fill_between(
months_scale,
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] - stats.t.ppf(1 - 0.025, n_update_HadCM_old_4PIC_D47) * std_likelihood[var_start_D47_monthly:var_end_D47_monthly] / np.sqrt(n_update_HadCM_old_4PIC_D47),
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] + stats.t.ppf(1 - 0.025, n_update_HadCM_old_4PIC_D47) * std_likelihood[var_start_D47_monthly:var_end_D47_monthly] / np.sqrt(n_update_HadCM_old_4PIC_D47),
color='y',
alpha=0.2,
label='95% Confidence Interval'
)
# POSTERIOR
axs[0, 6].plot(months_scale, mu_post_HadCM_old_4PIC_SST_D47, label='Posterior Mean', color='r', marker='o')
axs[0, 6].fill_between(
months_scale,
mu_post_HadCM_old_4PIC_SST_D47 - stats.t.ppf(1 - 0.025, (n_update_HadCM_old_4PIC_D47 + n_models_HadCM_old_4PIC_monthly)) * std_post_HadCM_old_4PIC_SST_D47 / np.sqrt(n_update_HadCM_old_4PIC_D47 + n_models_HadCM_old_4PIC_monthly),
mu_post_HadCM_old_4PIC_SST_D47 + stats.t.ppf(1 - 0.025, (n_update_HadCM_old_4PIC_D47 + n_models_HadCM_old_4PIC_monthly)) * std_post_HadCM_old_4PIC_SST_D47 / np.sqrt(n_update_HadCM_old_4PIC_D47 + n_models_HadCM_old_4PIC_monthly),
color='r',
alpha=0.2,
label='95% Confidence Interval (Posterior)'
)
# Formatting
axs[0, 6].set_xticks(months_scale, month_names)
axs[0, 6].set_title('HadCM (old)\n4x preindustrial pCO2')
axs[0, 6].set_xlabel('Month')
axs[0, 6].set_ylabel('SST D47 value')
axs[0, 6].legend()
axs[0, 6].grid(True)
# ---d18Oc---
# PRIOR
axs[1, 6].plot(months_scale, mu_prior_HadCM_old_4PIC_d18Oc_monthly_original, label='Prior Mean', color='b', marker='o')
axs[1, 6].fill_between(
months_scale,
mu_prior_HadCM_old_4PIC_d18Oc_monthly_original - stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_d18Oc_monthly_original / np.sqrt(n_models_HadCM_old_4PIC_monthly),
mu_prior_HadCM_old_4PIC_d18Oc_monthly_original + stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_d18Oc_monthly_original / np.sqrt(n_models_HadCM_old_4PIC_monthly),
color='b',
alpha=0.2,
label='95% Confidence Interval'
)
# LIKELIHOOD
axs[1, 6].plot(months_scale, mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly], label='Likelihood Mean', color='y', marker='o')
axs[1, 6].fill_between(
months_scale,
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] - stats.t.ppf(1 - 0.025, n_update_HadCM_old_4PIC_d18Oc) * std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] / np.sqrt(n_update_HadCM_old_4PIC_d18Oc),
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] + stats.t.ppf(1 - 0.025, n_update_HadCM_old_4PIC_d18Oc) * std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] / np.sqrt(n_update_HadCM_old_4PIC_d18Oc),
color='y',
alpha=0.2,
label='95% Confidence Interval'
)
# POSTERIOR
axs[1, 6].plot(months_scale, mu_post_HadCM_old_4PIC_d18Oc, label='Posterior Mean', color='r', marker='o')
axs[1, 6].fill_between(
months_scale,
mu_post_HadCM_old_4PIC_d18Oc - stats.t.ppf(1 - 0.025, (n_update_HadCM_old_4PIC_d18Oc + n_models_HadCM_old_4PIC_monthly)) * std_post_HadCM_old_4PIC_d18Oc / np.sqrt(n_update_HadCM_old_4PIC_d18Oc + n_models_HadCM_old_4PIC_monthly),
mu_post_HadCM_old_4PIC_d18Oc + stats.t.ppf(1 - 0.025, (n_update_HadCM_old_4PIC_d18Oc + n_models_HadCM_old_4PIC_monthly)) * std_post_HadCM_old_4PIC_d18Oc / np.sqrt(n_update_HadCM_old_4PIC_d18Oc + n_models_HadCM_old_4PIC_monthly),
color='r',
alpha=0.2,
label='95% Confidence Interval (Posterior)'
)
# Formatting
axs[1, 6].set_xticks(months_scale, month_names, rotation=45, ha='right')
axs[1, 6].set_xlabel('Month')
axs[1, 6].set_ylabel('d18Oc value')
axs[1, 6].legend()
axs[1, 6].grid(True)
plt.suptitle('Monthly Prior and Posterior Means with 95% Confidence Intervals', fontsize = 16)
plt.show()
PLOT PRIOR AND LIKELIHOOD FOR MANUSCRIPT¶
In [74]:
# Set dimensions of data
n_models_monthly = len(Lutetian_CESM_2PIC_model["Cell"]) # Find the total number of models
# Create list of month names
months = ['ja', 'fb', 'mr', 'ar', 'my', 'jn', 'jl', 'ag', 'sp', 'ot', 'nv', 'dc']
# Create a monthly scale for the x-axis
month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] # List full month names
months_scale = np.arange(len(months)) + 1 # Create monthly scale
# Create the figure and axes
fig, axes = plt.subplots(7, 3, figsize=(18, 20), sharex=True)
# Start with DA based on CESM model outcomes with 4x preindustrial pCO2 forcing
# Panel 1: Plot the prior distribution for SST and SAT
axes[0, 0].plot(months_scale, mu_prior_CESM_2PIC_SAT_monthly, label='Prior SAT Mean', marker='o', color='r')
axes[0, 0].plot(months_scale, mu_prior_CESM_2PIC_SST_monthly, label='Prior SST Mean', marker='o', color='b')
# Add 95% confidence intervals for SAT
axes[0, 0].fill_between(
months_scale,
mu_prior_CESM_2PIC_SAT_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SAT_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_SAT_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SAT_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
alpha=0.2, color='r', label='SAT 95% CI'
)
# Add 95% confidence intervals for SST
axes[0, 0].fill_between(
months_scale,
mu_prior_CESM_2PIC_SST_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SST_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_SST_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SST_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
alpha=0.2, color='b', label='SST 95% CI'
)
# axes[0].set_title('Prior Mean and 95% Confidence Interval for Monthly SST & SAT Values')
axes[0, 0].set_ylabel('Temperature (°C)')
axes[0, 0].legend()
axes[0, 0].grid(True)
# Panel 2: Plot the prior distribution for SSS and precipitation
axes[0, 1].plot(months_scale, mu_prior_CESM_2PIC_SSS_monthly, label='Prior SSS Mean', marker='o', color='g')
ax2 = axes[0, 1].twinx() # Create a secondary y-axis for precipitation
ax2.plot(months_scale, mu_prior_CESM_2PIC_precip_monthly, label='Prior Precipitation Mean', marker='o', color='purple')
# Add 95% confidence intervals for SSS
axes[0, 1].fill_between(
months_scale,
mu_prior_CESM_2PIC_SSS_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SSS_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_SSS_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SSS_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
alpha=0.2, color='g', label='SSS 95% CI'
)
# Add 95% confidence intervals for precipitation
ax2.fill_between(
months_scale,
mu_prior_CESM_2PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_precip_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_precip_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
alpha=0.2, color='purple', label='Precipitation 95% CI'
)
axes[0, 1].set_ylabel('SSS (psu)', color='g')
ax2.set_ylabel('Precipitation (mm/day)', color='purple')
axes[0, 1].set_title('Priors and likelihoods for Lutetian case study')
axes[0, 1].legend(loc='upper left')
ax2.legend(loc='upper right')
axes[0, 1].grid(True)
# Panel 3: Plot the likelihood distribution for D47 and d18Oc measurements
# Plot individual (non-aggregated) measurements with uncertainties
ax3 = axes[0, 2].twinx() # secondary y-axis for d18Oc
# Plot D47 likelihood
# Determine the start and end indices for the selected variable to parse information from the likelihood statistics
axes[0, 2].plot(months_scale, mu_likelihood[var_start_D47_monthly:var_end_D47_monthly], marker='o', label='D47 means', color='darkred')
axes[0, 2].fill_between(
months_scale,
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] - 1.96 * np.sqrt(std_likelihood[var_start_D47_monthly:var_end_D47_monthly]),
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] + 1.96 * np.sqrt(std_likelihood[var_start_D47_monthly:var_end_D47_monthly]),
color='darkred',
alpha=0.2,
label='D47 95% CI'
)
for measurement in Lutetian_data_dict:
x_jitter = measurement["month_score"] + 1 + np.random.uniform(-0.2, 0.2)
axes[0, 2].plot(x_jitter, measurement["D47_final"], color="darkred", marker="o", alpha=0.2)
axes[0, 2].errorbar(x_jitter, measurement["D47_final"], yerr=measurement["D47_SD"], color="darkred", alpha=0.2)
# Plot d18Oc likelihood
# Determine the start and end indices for the selected variable
ax3.plot(months_scale, mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly], marker='o', label='d18Oc means', color='darkblue')
ax3.fill_between(
months_scale,
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] - 1.96 * np.sqrt(std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly]),
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] + 1.96 * np.sqrt(std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly]),
color='darkblue',
alpha=0.2,
label='d18Oc 95% CI'
)
for measurement in Lutetian_data_dict:
x_jitter = measurement["month_score"] + 1 + np.random.uniform(-0.2, 0.2)
ax3.plot(x_jitter, measurement["d18O"], color="darkblue", marker="o", alpha=0.2)
ax3.errorbar(x_jitter, measurement["d18O"], yerr=measurement["d18O_SD"], color="darkblue", alpha=0.2)
axes[0, 2].set_ylabel('D47 (per mille I-CDES)', color='darkred')
ax3.set_ylabel('d18Oc (per mille VPDB)', color='darkblue')
axes[0, 2].legend(loc='upper left')
ax3.legend(loc='upper right')
axes[0, 2].grid(True)
# # Update the x-axis with month names
axes[0, 0].set_xticks(months_scale)
axes[0, 0].set_xticklabels(month_names, rotation=45, ha="right")
axes[0, 1].set_xticklabels(month_names, rotation=45, ha="right")
axes[0, 2].set_xticklabels(month_names, rotation=45, ha="right")
# Fill lower row of plot with DA outcomes based on CESM model with 2x preindustrial pCO2 forcing
# Panel 1: Plot the prior distribution for SST and SAT
axes[1, 0].plot(months_scale, mu_prior_CESM_2PIC_SAT_monthly, label='Prior SAT Mean', marker='o', color='r')
axes[1, 0].plot(months_scale, mu_prior_CESM_2PIC_SST_monthly, label='Prior SST Mean', marker='o', color='b')
# Add 95% confidence intervals for SAT
axes[1, 0].fill_between(
months_scale,
mu_prior_CESM_2PIC_SAT_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SAT_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_SAT_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SAT_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
alpha=0.2, color='r', label='SAT 95% CI'
)
# Add 95% confidence intervals for SST
axes[1, 0].fill_between(
months_scale,
mu_prior_CESM_2PIC_SST_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SST_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_SST_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SST_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
alpha=0.2, color='b', label='SST 95% CI'
)
# axes[0].set_title('Prior Mean and 95% Confidence Interval for Monthly SST & SAT Values')
axes[1, 0].set_ylabel('Temperature (°C)')
axes[1, 0].legend()
axes[1, 0].grid(True)
# Panel 2: Plot the prior distribution for SSS and precipitation
axes[1, 1].plot(months_scale, mu_prior_CESM_2PIC_SSS_monthly, label='Prior SSS Mean', marker='o', color='g')
ax4 = axes[1, 1].twinx() # Create a secondary y-axis for precipitation
ax4.plot(months_scale, mu_prior_CESM_2PIC_precip_monthly, label='Prior Precipitation Mean', marker='o', color='purple')
# Add 95% confidence intervals for SSS
axes[1, 1].fill_between(
months_scale,
mu_prior_CESM_2PIC_SSS_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SSS_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_SSS_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SSS_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
alpha=0.2, color='g', label='SSS 95% CI'
)
# Add 95% confidence intervals for precipitation
ax4.fill_between(
months_scale,
mu_prior_CESM_2PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_precip_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_precip_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
alpha=0.2, color='purple', label='Precipitation 95% CI'
)
axes[1, 1].set_ylabel('SSS (psu)', color='g')
ax4.set_ylabel('Precipitation (mm/day)', color='purple')
axes[1, 1].set_title('Priors and likelihoods for Lutetian case study')
axes[1, 1].legend(loc='upper left')
ax4.legend(loc='upper right')
axes[1, 1].grid(True)
# Panel 3: Plot the likelihood distribution for D47 and d18Oc measurements
# Plot individual (non-aggregated) measurements with uncertainties
ax5 = axes[1, 2].twinx() # secondary y-axis for d18Oc
# Plot D47 likelihood
# Determine the start and end indices for the selected variable to parse information from the likelihood statistics
axes[1, 2].plot(months_scale, mu_likelihood[var_start_D47_monthly:var_end_D47_monthly], marker='o', label='D47 means', color='darkred')
axes[1, 2].fill_between(
months_scale,
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] - 1.96 * np.sqrt(std_likelihood[var_start_D47_monthly:var_end_D47_monthly]),
mu_likelihood[var_start_D47_monthly:var_end_D47_monthly] + 1.96 * np.sqrt(std_likelihood[var_start_D47_monthly:var_end_D47_monthly]),
color='darkred',
alpha=0.2,
label='D47 95% CI'
)
for measurement in Lutetian_data_dict:
x_jitter = measurement["month_score"] + 1 + np.random.uniform(-0.2, 0.2)
axes[1, 2].plot(x_jitter, measurement["D47_final"], color="darkred", marker="o", alpha=0.2)
axes[1, 2].errorbar(x_jitter, measurement["D47_final"], yerr=measurement["D47_SD"], color="darkred", alpha=0.2)
# Plot d18Oc likelihood
# Determine the start and end indices for the selected variable
ax5.plot(months_scale, mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly], marker='o', label='d18Oc means', color='darkblue')
ax5.fill_between(
months_scale,
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] - 1.96 * np.sqrt(std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly]),
mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] + 1.96 * np.sqrt(std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly]),
color='darkblue',
alpha=0.2,
label='d18Oc 95% CI'
)
for measurement in Lutetian_data_dict:
x_jitter = measurement["month_score"] + 1 + np.random.uniform(-0.2, 0.2)
ax3.plot(x_jitter, measurement["d18O"], color="darkblue", marker="o", alpha=0.2)
ax3.errorbar(x_jitter, measurement["d18O"], yerr=measurement["d18O_SD"], color="darkblue", alpha=0.2)
axes[1, 2].set_ylabel('D47 (per mille I-CDES)', color='darkred')
ax5.set_ylabel('d18Oc (per mille VPDB)', color='darkblue')
axes[1, 2].legend(loc='upper left')
ax5.legend(loc='upper right')
axes[1, 2].grid(True)
# # Update the x-axis with month names
axes[1, 0].set_xticks(months_scale)
axes[1, 0].set_xticklabels(month_names, rotation=45, ha="right")
axes[1, 1].set_xticklabels(month_names, rotation=45, ha="right")
axes[1, 2].set_xticklabels(month_names, rotation=45, ha="right")
# Set tight layout
fig.suptitle('Lutetian Case Study: Monthly Prior and Likelihood Means with 95% Confidence Intervals (CESM 2x preindustrial pCO2)', fontsize = 16)
plt.tight_layout()
POSTERIOR - MONTHLY¶
Monthly posterior in temperature and salinity domains with aggregated data¶
- Data and model outcomes assembled per month
- Ignore sclero-dating uncertainty
- D47 data aggregated in monthly bins prior to assembly
Convert monthly prior, likelihood and posterior to temperature and salinity and plot¶
To calculate the covariance matrices for d18Ow based on covariance between d18Oc values for the equations of Grossman and Ku and Lecuyer et al. the following approach is followed:
- Original formula: T = B - A * (d18Oc - d18Ow) (+ 0.27 for Grossman and Ku, but this term is irrelavant for covariance; A and B different per calibration equation)
First solve for d18Ow:
- d18Ow (in VSMOW) = d18Oc - (B - T) / A (+ 0.27)
- Partial derivative 1: d(d18Ow)/d(d18Oc) = 1
- Partial derivative 2: d(d18Ow)/d(T) = 1 / A
- cov(d18Ow) = d(d18Ow)/d(d18Oc) ^ 2 * cov(d18Oc) + d(d18Ow)/d(d18Oc) * d(d18Ow)/d(T) * crosscov(d18Oc, T) * transpose(crosscov(d18Oc, T)) + d(d18Ow)/d(T) ^ 2 * cov(T)
Define function for propagating uncertainty through d18Oc-d18Ow-temperature relationship¶
In [75]:
# Function to propagate covariance on d18Ow in case of linear d18Oc-d18Ow-T equation
def propagate_cov_d18Ow_linear(cov_c, cov_T, cov_cT, A):
"""
Propagate covariance for:
w = c - (B - T)/A (+ 0.27)
where A and B are scalars and the term 0.27 is used to convert between SMOW and VSMOW, but only A is relevant for covariance
Inputs:
cov_c : (n,n) covariance matrix of d18Oc
cov_T : (n,n) covariance matrix of T
cov_cT : (n,n) cross-covariance matrix Cov(c,T)
A : scalar (slope)
Returns:
cov_w : (n,n) covariance matrix of d18Ow
"""
dwdc = 1.0
dwdT = 1.0 / A
cov_w = (
dwdc**2 * cov_c
+ dwdc * dwdT * (cov_cT + cov_cT.T)
+ dwdT**2 * cov_T
)
return cov_w
Execute SST and SSS error propagation for all model scenarios¶
In [76]:
# Convert prior D47 to temp
mu_prior_CESM_4PIC_SST_D47_monthly_T = D47c.OGLS23.T47(D47 = mu_prior_CESM_4PIC_SST_D47_monthly_original, sD47 = cov_prior_CESM_4PIC_SST_D47_monthly_original, return_covar = True)[0]
mu_prior_CESM_2PIC_SST_D47_monthly_T = D47c.OGLS23.T47(D47 = mu_prior_CESM_2PIC_SST_D47_monthly_original, sD47 = cov_prior_CESM_2PIC_SST_D47_monthly_original, return_covar = True)[0]
mu_prior_HadCM_new_1PIC_SST_D47_monthly_T = D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_1PIC_SST_D47_monthly_original, sD47 = cov_prior_HadCM_new_1PIC_SST_D47_monthly_original, return_covar = True)[0]
mu_prior_HadCM_new_2PIC_SST_D47_monthly_T = D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_2PIC_SST_D47_monthly_original, sD47 = cov_prior_HadCM_new_2PIC_SST_D47_monthly_original, return_covar = True)[0]
mu_prior_HadCM_new_1056ppm_SST_D47_monthly_T = D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_1056ppm_SST_D47_monthly_original, sD47 = cov_prior_HadCM_new_1056ppm_SST_D47_monthly_original, return_covar = True)[0]
mu_prior_HadCM_old_2PIC_SST_D47_monthly_T = D47c.OGLS23.T47(D47 = mu_prior_HadCM_old_2PIC_SST_D47_monthly_original, sD47 = cov_prior_HadCM_old_2PIC_SST_D47_monthly_original, return_covar = True)[0]
mu_prior_HadCM_old_4PIC_SST_D47_monthly_T = D47c.OGLS23.T47(D47 = mu_prior_HadCM_old_4PIC_SST_D47_monthly_original, sD47 = cov_prior_HadCM_old_4PIC_SST_D47_monthly_original, return_covar = True)[0]
cov_prior_CESM_4PIC_SST_D47_monthly_T = D47c.OGLS23.T47(D47 = mu_prior_CESM_4PIC_SST_D47_monthly_original, sD47 = cov_prior_CESM_4PIC_SST_D47_monthly_original, return_covar = True)[1]
cov_prior_CESM_2PIC_SST_D47_monthly_T = D47c.OGLS23.T47(D47 = mu_prior_CESM_2PIC_SST_D47_monthly_original, sD47 = cov_prior_CESM_2PIC_SST_D47_monthly_original, return_covar = True)[1]
cov_prior_HadCM_new_1PIC_SST_D47_monthly_T = D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_1PIC_SST_D47_monthly_original, sD47 = cov_prior_HadCM_new_1PIC_SST_D47_monthly_original, return_covar = True)[1]
cov_prior_HadCM_new_2PIC_SST_D47_monthly_T = D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_2PIC_SST_D47_monthly_original, sD47 = cov_prior_HadCM_new_2PIC_SST_D47_monthly_original, return_covar = True)[1]
cov_prior_HadCM_new_1056ppm_SST_D47_monthly_T = D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_1056ppm_SST_D47_monthly_original, sD47 = cov_prior_HadCM_new_1056ppm_SST_D47_monthly_original, return_covar = True)[1]
cov_prior_HadCM_old_2PIC_SST_D47_monthly_T = D47c.OGLS23.T47(D47 = mu_prior_HadCM_old_2PIC_SST_D47_monthly_original, sD47 = cov_prior_HadCM_old_2PIC_SST_D47_monthly_original, return_covar = True)[1]
cov_prior_HadCM_old_4PIC_SST_D47_monthly_T = D47c.OGLS23.T47(D47 = mu_prior_HadCM_old_4PIC_SST_D47_monthly_original, sD47 = cov_prior_HadCM_old_4PIC_SST_D47_monthly_original, return_covar = True)[1]
# Convert prior d18Oc and temperature to d18Ow
mu_prior_CESM_4PIC_d18Ow_monthly_T = mu_prior_CESM_4PIC_d18Oc_monthly_original - (20.6 - mu_prior_CESM_4PIC_SST_D47_monthly_T) / 4.34 + 0.27
mu_prior_CESM_2PIC_d18Ow_monthly_T = mu_prior_CESM_2PIC_d18Oc_monthly_original - (20.6 - mu_prior_CESM_2PIC_SST_D47_monthly_T) / 4.34 + 0.27
mu_prior_HadCM_new_1PIC_d18Ow_monthly_T = mu_prior_HadCM_new_1PIC_d18Oc_monthly_original - (20.6 - mu_prior_HadCM_new_1PIC_SST_D47_monthly_T) / 4.34 + 0.27
mu_prior_HadCM_new_2PIC_d18Ow_monthly_T = mu_prior_HadCM_new_2PIC_d18Oc_monthly_original - (20.6 - mu_prior_HadCM_new_2PIC_SST_D47_monthly_T) / 4.34 + 0.27
mu_prior_HadCM_new_1056ppm_d18Ow_monthly_T = mu_prior_HadCM_new_1056ppm_d18Oc_monthly_original - (20.6 - mu_prior_HadCM_new_1056ppm_SST_D47_monthly_T) / 4.34 + 0.27
mu_prior_HadCM_old_2PIC_d18Ow_monthly_T = mu_prior_HadCM_old_2PIC_d18Oc_monthly_original - (20.6 - mu_prior_HadCM_old_2PIC_SST_D47_monthly_T) / 4.34 + 0.27
mu_prior_HadCM_old_4PIC_d18Ow_monthly_T = mu_prior_HadCM_old_4PIC_d18Oc_monthly_original - (20.6 - mu_prior_HadCM_old_4PIC_SST_D47_monthly_T) / 4.34 + 0.27
# Calculate d18Oc-SST cross-covariance matrix
cross_cov_prior_CESM_4PIC_d18Oc_SST_monthly = np.cov(Lutetian_CESM_4PIC_model[SST_D47_CESM_4PIC_columns_monthly + d18Oc_CESM_4PIC_columns_monthly].dropna(), rowvar=False)[len(SST_D47_CESM_4PIC_columns_monthly):, :len(SST_D47_CESM_4PIC_columns_monthly)]
cross_cov_prior_CESM_2PIC_d18Oc_SST_monthly = np.cov(Lutetian_CESM_2PIC_model[SST_D47_CESM_2PIC_columns_monthly + d18Oc_CESM_2PIC_columns_monthly].dropna(), rowvar=False)[len(SST_D47_CESM_2PIC_columns_monthly):, :len(SST_D47_CESM_2PIC_columns_monthly)]
cross_cov_prior_HadCM_new_1PIC_d18Oc_SST_monthly = np.cov(Lutetian_HadCM_new_1PIC_model[SST_D47_HadCM_new_1PIC_columns_monthly + d18Oc_HadCM_new_1PIC_columns_monthly].dropna(), rowvar=False)[len(SST_D47_HadCM_new_1PIC_columns_monthly):, :len(SST_D47_HadCM_new_1PIC_columns_monthly)]
cross_cov_prior_HadCM_new_2PIC_d18Oc_SST_monthly = np.cov(Lutetian_HadCM_new_2PIC_model[SST_D47_HadCM_new_2PIC_columns_monthly + d18Oc_HadCM_new_2PIC_columns_monthly].dropna(), rowvar=False)[len(SST_D47_HadCM_new_2PIC_columns_monthly):, :len(SST_D47_HadCM_new_2PIC_columns_monthly)]
cross_cov_prior_HadCM_new_1056ppm_d18Oc_SST_monthly = np.cov(Lutetian_HadCM_new_1056ppm_model[SST_D47_HadCM_new_1056ppm_columns_monthly + d18Oc_HadCM_new_1056ppm_columns_monthly].dropna(), rowvar=False)[len(SST_D47_HadCM_new_1056ppm_columns_monthly):, :len(SST_D47_HadCM_new_1056ppm_columns_monthly)]
cross_cov_prior_HadCM_old_2PIC_d18Oc_SST_monthly = np.cov(Lutetian_HadCM_old_2PIC_model[SST_D47_HadCM_old_2PIC_columns_monthly + d18Oc_HadCM_old_2PIC_columns_monthly].dropna(), rowvar=False)[len(SST_D47_HadCM_old_2PIC_columns_monthly):, :len(SST_D47_HadCM_old_2PIC_columns_monthly)]
cross_cov_prior_HadCM_old_4PIC_d18Oc_SST_monthly = np.cov(Lutetian_HadCM_old_4PIC_model[SST_D47_HadCM_old_4PIC_columns_monthly + d18Oc_HadCM_old_4PIC_columns_monthly].dropna(), rowvar=False)[len(SST_D47_HadCM_old_4PIC_columns_monthly):, :len(SST_D47_HadCM_old_4PIC_columns_monthly)]
# Propagate covariance
cov_prior_CESM_4PIC_d18Ow_monthly_T = propagate_cov_d18Ow_linear(cov_prior_CESM_4PIC_d18Oc_monthly_original, cov_prior_CESM_4PIC_SST_D47_monthly_T, cross_cov_prior_CESM_4PIC_d18Oc_SST_monthly, 4.34)
cov_prior_CESM_2PIC_d18Ow_monthly_T = propagate_cov_d18Ow_linear(cov_prior_CESM_2PIC_d18Oc_monthly_original, cov_prior_CESM_2PIC_SST_D47_monthly_T, cross_cov_prior_CESM_2PIC_d18Oc_SST_monthly, 4.34)
cov_prior_HadCM_new_1PIC_d18Ow_monthly_T = propagate_cov_d18Ow_linear(cov_prior_HadCM_new_1PIC_d18Oc_monthly_original, cov_prior_HadCM_new_1PIC_SST_D47_monthly_T, cross_cov_prior_HadCM_new_1PIC_d18Oc_SST_monthly, 4.34)
cov_prior_HadCM_new_2PIC_d18Ow_monthly_T = propagate_cov_d18Ow_linear(cov_prior_HadCM_new_2PIC_d18Oc_monthly_original, cov_prior_HadCM_new_2PIC_SST_D47_monthly_T, cross_cov_prior_HadCM_new_2PIC_d18Oc_SST_monthly, 4.34)
cov_prior_HadCM_new_1056ppm_d18Ow_monthly_T = propagate_cov_d18Ow_linear(cov_prior_HadCM_new_1056ppm_d18Oc_monthly_original, cov_prior_HadCM_new_1056ppm_SST_D47_monthly_T, cross_cov_prior_HadCM_new_1056ppm_d18Oc_SST_monthly, 4.34)
cov_prior_HadCM_old_2PIC_d18Ow_monthly_T = propagate_cov_d18Ow_linear(cov_prior_HadCM_old_2PIC_d18Oc_monthly_original, cov_prior_HadCM_old_2PIC_SST_D47_monthly_T, cross_cov_prior_HadCM_old_2PIC_d18Oc_SST_monthly, 4.34)
cov_prior_HadCM_old_4PIC_d18Ow_monthly_T = propagate_cov_d18Ow_linear(cov_prior_HadCM_old_4PIC_d18Oc_monthly_original, cov_prior_HadCM_old_4PIC_SST_D47_monthly_T, cross_cov_prior_HadCM_old_4PIC_d18Oc_SST_monthly, 4.34)
# Convert prior d18Ow to SSS
mu_prior_CESM_4PIC_SSS_d18Ow_monthly_T = (mu_prior_CESM_4PIC_d18Ow_monthly_T + 9.300) / 0.274
mu_prior_CESM_2PIC_SSS_d18Ow_monthly_T = (mu_prior_CESM_2PIC_d18Ow_monthly_T + 9.300) / 0.274
mu_prior_HadCM_new_1PIC_SSS_d18Ow_monthly_T = (mu_prior_HadCM_new_1PIC_d18Ow_monthly_T + 9.300) / 0.274
mu_prior_HadCM_new_2PIC_SSS_d18Ow_monthly_T = (mu_prior_HadCM_new_2PIC_d18Ow_monthly_T + 9.300) / 0.274
mu_prior_HadCM_new_1056ppm_SSS_d18Ow_monthly_T = (mu_prior_HadCM_new_1056ppm_d18Ow_monthly_T + 9.300) / 0.274
mu_prior_HadCM_old_2PIC_SSS_d18Ow_monthly_T = (mu_prior_HadCM_old_2PIC_d18Ow_monthly_T + 9.300) / 0.274
mu_prior_HadCM_old_4PIC_SSS_d18Ow_monthly_T = (mu_prior_HadCM_old_4PIC_d18Ow_monthly_T + 9.300) / 0.274
cov_prior_CESM_4PIC_SSS_d18Ow_monthly_T = cov_prior_CESM_4PIC_d18Ow_monthly_T / (0.274 ** 2)
cov_prior_CESM_2PIC_SSS_d18Ow_monthly_T = cov_prior_CESM_2PIC_d18Ow_monthly_T / (0.274 ** 2)
cov_prior_HadCM_new_1PIC_SSS_d18Ow_monthly_T = cov_prior_HadCM_new_1PIC_d18Ow_monthly_T / (0.274 ** 2)
cov_prior_HadCM_new_2PIC_SSS_d18Ow_monthly_T = cov_prior_HadCM_new_2PIC_d18Ow_monthly_T / (0.274 ** 2)
cov_prior_HadCM_new_1056ppm_SSS_d18Ow_monthly_T = cov_prior_HadCM_new_1056ppm_d18Ow_monthly_T / (0.274 ** 2)
cov_prior_HadCM_old_2PIC_SSS_d18Ow_monthly_T = cov_prior_HadCM_old_2PIC_d18Ow_monthly_T / (0.274 ** 2)
cov_prior_HadCM_old_4PIC_SSS_d18Ow_monthly_T = cov_prior_HadCM_old_4PIC_d18Ow_monthly_T / (0.274 ** 2)
# Convert likelihood D47 to temp
# FIXME: likelihood vectors contain NAs, need to handle that properly
mu_likelihood_T = D47c.OGLS23.T47(D47 = mu_likelihood[var_start_D47_monthly:var_end_D47_monthly], sD47 = std_likelihood[var_start_D47_monthly:var_end_D47_monthly], return_covar = True)[0]
cov_likelihood_T = D47c.OGLS23.T47(D47 = mu_likelihood[var_start_D47_monthly:var_end_D47_monthly], sD47 = std_likelihood[var_start_D47_monthly:var_end_D47_monthly], return_covar = True)[1]
# Convert likelihood d18Oc and temperature to d18Ow (curently not implemented in data tracking function)
mu_likelihood_d18Ow_T = mu_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] - (20.6 - mu_likelihood_T) / 4.34 + 0.27
std_likelihood_d18Ow_T = np.sqrt(
np.diag(
propagate_cov_d18Ow_linear(
np.diag(std_likelihood[var_start_d18Oc_monthly:var_end_d18Oc_monthly] ** 2),
cov_likelihood_T,
cross_cov_prior_CESM_4PIC_d18Oc_SST_monthly,
4.34
)
)
)
# Convert likelihood d18Ow to SSS (currently not implemented in data tracking function)
mu_likelihood_SSS_d18Ow_T = (mu_likelihood_d18Ow_T + 9.300) / 0.274
std_likelihood_SSS_d18Ow_T = std_likelihood_d18Ow_T / (0.274 ** 2)
# Convert posterior D47 to temp
mu_post_CESM_4PIC_SST_D47_T = D47c.OGLS23.T47(D47 = mu_post_CESM_4PIC_SST_D47, sD47 = cov_post_CESM_4PIC_SST_D47, return_covar = True)[0]
mu_post_CESM_2PIC_SST_D47_T = D47c.OGLS23.T47(D47 = mu_post_CESM_2PIC_SST_D47, sD47 = cov_post_CESM_2PIC_SST_D47, return_covar = True)[0]
mu_post_HadCM_new_1PIC_SST_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_1PIC_SST_D47, sD47 = cov_post_HadCM_new_1PIC_SST_D47, return_covar = True)[0]
mu_post_HadCM_new_2PIC_SST_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_2PIC_SST_D47, sD47 = cov_post_HadCM_new_2PIC_SST_D47, return_covar = True)[0]
mu_post_HadCM_new_1056ppm_SST_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_1056ppm_SST_D47, sD47 = cov_post_HadCM_new_1056ppm_SST_D47, return_covar = True)[0]
mu_post_HadCM_old_2PIC_SST_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_old_2PIC_SST_D47, sD47 = cov_post_HadCM_old_2PIC_SST_D47, return_covar = True)[0]
mu_post_HadCM_old_4PIC_SST_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_old_4PIC_SST_D47, sD47 = cov_post_HadCM_old_4PIC_SST_D47, return_covar = True)[0]
cov_post_CESM_4PIC_SST_D47_T = D47c.OGLS23.T47(D47 = mu_post_CESM_4PIC_SST_D47, sD47 = cov_post_CESM_4PIC_SST_D47, return_covar = True)[1]
cov_post_CESM_2PIC_SST_D47_T = D47c.OGLS23.T47(D47 = mu_post_CESM_2PIC_SST_D47, sD47 = cov_post_CESM_2PIC_SST_D47, return_covar = True)[1]
cov_post_HadCM_new_1PIC_SST_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_1PIC_SST_D47, sD47 = cov_post_HadCM_new_1PIC_SST_D47, return_covar = True)[1]
cov_post_HadCM_new_2PIC_SST_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_2PIC_SST_D47, sD47 = cov_post_HadCM_new_2PIC_SST_D47, return_covar = True)[1]
cov_post_HadCM_new_1056ppm_SST_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_1056ppm_SST_D47, sD47 = cov_post_HadCM_new_1056ppm_SST_D47, return_covar = True)[1]
cov_post_HadCM_old_2PIC_SST_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_old_2PIC_SST_D47, sD47 = cov_post_HadCM_old_2PIC_SST_D47, return_covar = True)[1]
cov_post_HadCM_old_4PIC_SST_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_old_4PIC_SST_D47, sD47 = cov_post_HadCM_old_4PIC_SST_D47, return_covar = True)[1]
# Convert posterior d18Oc and temperature to d18Ow
mu_post_CESM_4PIC_d18Ow_T = mu_post_CESM_4PIC_d18Oc - (20.6 - mu_post_CESM_4PIC_SST_D47_T) / 4.34 + 0.27
mu_post_CESM_2PIC_d18Ow_T = mu_post_CESM_2PIC_d18Oc - (20.6 - mu_post_CESM_2PIC_SST_D47_T) / 4.34 + 0.27
mu_post_HadCM_new_1PIC_d18Ow_T = mu_post_HadCM_new_1PIC_d18Oc - (20.6 - mu_post_HadCM_new_1PIC_SST_D47_T) / 4.34 + 0.27
mu_post_HadCM_new_2PIC_d18Ow_T = mu_post_HadCM_new_2PIC_d18Oc - (20.6 - mu_post_HadCM_new_2PIC_SST_D47_T) / 4.34 + 0.27
mu_post_HadCM_new_1056ppm_d18Ow_T = mu_post_HadCM_new_1056ppm_d18Oc - (20.6 - mu_post_HadCM_new_1056ppm_SST_D47_T) / 4.34 + 0.27
mu_post_HadCM_old_2PIC_d18Ow_T = mu_post_HadCM_old_2PIC_d18Oc - (20.6 - mu_post_HadCM_old_2PIC_SST_D47_T) / 4.34 + 0.27
mu_post_HadCM_old_4PIC_d18Ow_T = mu_post_HadCM_old_4PIC_d18Oc - (20.6 - mu_post_HadCM_old_4PIC_SST_D47_T) / 4.34 + 0.27
# Propagate covariance
cov_post_CESM_4PIC_d18Ow_T = propagate_cov_d18Ow_linear(
cov_post_CESM_4PIC_d18Oc,
cov_post_CESM_4PIC_SST_D47_T,
cross_cov_prior_CESM_4PIC_d18Oc_SST_monthly,
4.34
)
cov_post_CESM_2PIC_d18Ow_T = propagate_cov_d18Ow_linear(
cov_post_CESM_2PIC_d18Oc,
cov_post_CESM_2PIC_SST_D47_T,
cross_cov_prior_CESM_2PIC_d18Oc_SST_monthly,
4.34
)
cov_post_HadCM_new_1PIC_d18Ow_T = propagate_cov_d18Ow_linear(
cov_post_HadCM_new_1PIC_d18Oc,
cov_post_HadCM_new_1PIC_SST_D47_T,
cross_cov_prior_HadCM_new_1PIC_d18Oc_SST_monthly,
4.34
)
cov_post_HadCM_new_2PIC_d18Ow_T = propagate_cov_d18Ow_linear(
cov_post_HadCM_new_2PIC_d18Oc,
cov_post_HadCM_new_2PIC_SST_D47_T,
cross_cov_prior_HadCM_new_2PIC_d18Oc_SST_monthly,
4.34
)
cov_post_HadCM_new_1056ppm_d18Ow_T = propagate_cov_d18Ow_linear(
cov_post_HadCM_new_1056ppm_d18Oc,
cov_post_HadCM_new_1056ppm_SST_D47_T,
cross_cov_prior_HadCM_new_1056ppm_d18Oc_SST_monthly,
4.34
)
cov_post_HadCM_old_2PIC_d18Ow_T = propagate_cov_d18Ow_linear(
cov_post_HadCM_old_2PIC_d18Oc,
cov_post_HadCM_old_2PIC_SST_D47_T,
cross_cov_prior_HadCM_old_2PIC_d18Oc_SST_monthly,
4.34
)
cov_post_HadCM_old_4PIC_d18Ow_T = propagate_cov_d18Ow_linear(
cov_post_HadCM_old_4PIC_d18Oc,
cov_post_HadCM_old_4PIC_SST_D47_T,
cross_cov_prior_HadCM_old_4PIC_d18Oc_SST_monthly,
4.34
)
# Convert posterior d18Ow to SSS
mu_post_CESM_4PIC_SSS_d18Ow_T = (mu_post_CESM_4PIC_d18Ow_T + 9.300) / 0.274
mu_post_CESM_2PIC_SSS_d18Ow_T = (mu_post_CESM_2PIC_d18Ow_T + 9.300) / 0.274
mu_post_HadCM_new_1PIC_SSS_d18Ow_T = (mu_post_HadCM_new_1PIC_d18Ow_T + 9.300) / 0.274
mu_post_HadCM_new_2PIC_SSS_d18Ow_T = (mu_post_HadCM_new_2PIC_d18Ow_T + 9.300) / 0.274
mu_post_HadCM_new_1056ppm_SSS_d18Ow_T = (mu_post_HadCM_new_1056ppm_d18Ow_T + 9.300) / 0.274
mu_post_HadCM_old_2PIC_SSS_d18Ow_T = (mu_post_HadCM_old_2PIC_d18Ow_T + 9.300) / 0.274
mu_post_HadCM_old_4PIC_SSS_d18Ow_T = (mu_post_HadCM_old_4PIC_d18Ow_T + 9.300) / 0.274
cov_post_CESM_4PIC_SSS_d18Ow_T = cov_post_CESM_4PIC_d18Ow_T / (0.274 ** 2)
cov_post_CESM_2PIC_SSS_d18Ow_T = cov_post_CESM_2PIC_d18Ow_T / (0.274 ** 2)
cov_post_HadCM_new_1PIC_SSS_d18Ow_T = cov_post_HadCM_new_1PIC_d18Ow_T / (0.274 ** 2)
cov_post_HadCM_new_2PIC_SSS_d18Ow_T = cov_post_HadCM_new_2PIC_d18Ow_T / (0.274 ** 2)
cov_post_HadCM_new_1056ppm_SSS_d18Ow_T = cov_post_HadCM_new_1056ppm_d18Ow_T / (0.274 ** 2)
cov_post_HadCM_old_2PIC_SSS_d18Ow_T = cov_post_HadCM_old_2PIC_d18Ow_T / (0.274 ** 2)
cov_post_HadCM_old_4PIC_SSS_d18Ow_T = cov_post_HadCM_old_4PIC_d18Ow_T / (0.274 ** 2)
# Standard deviations in temperature domain
std_prior_CESM_4PIC_SST_D47_monthly_T = np.sqrt(np.diag(cov_prior_CESM_4PIC_SST_D47_monthly_T))
std_prior_CESM_2PIC_SST_D47_monthly_T = np.sqrt(np.diag(cov_prior_CESM_2PIC_SST_D47_monthly_T))
std_prior_HadCM_new_1PIC_SST_D47_monthly_T = np.sqrt(np.diag(cov_prior_HadCM_new_1PIC_SST_D47_monthly_T))
std_prior_HadCM_new_2PIC_SST_D47_monthly_T = np.sqrt(np.diag(cov_prior_HadCM_new_2PIC_SST_D47_monthly_T))
std_prior_HadCM_new_1056ppm_SST_D47_monthly_T = np.sqrt(np.diag(cov_prior_HadCM_new_1056ppm_SST_D47_monthly_T))
std_prior_HadCM_old_2PIC_SST_D47_monthly_T = np.sqrt(np.diag(cov_prior_HadCM_old_2PIC_SST_D47_monthly_T))
std_prior_HadCM_old_4PIC_SST_D47_monthly_T = np.sqrt(np.diag(cov_prior_HadCM_old_4PIC_SST_D47_monthly_T))
std_prior_CESM_4PIC_SSS_d18Ow_monthly_T = np.sqrt(np.diag(cov_prior_CESM_4PIC_SSS_d18Ow_monthly_T))
std_prior_CESM_2PIC_SSS_d18Ow_monthly_T = np.sqrt(np.diag(cov_prior_CESM_2PIC_SSS_d18Ow_monthly_T))
std_prior_HadCM_new_1PIC_SSS_d18Ow_monthly_T = np.sqrt(np.diag(cov_prior_HadCM_new_1PIC_SSS_d18Ow_monthly_T))
std_prior_HadCM_new_2PIC_SSS_d18Ow_monthly_T = np.sqrt(np.diag(cov_prior_HadCM_new_2PIC_SSS_d18Ow_monthly_T))
std_prior_HadCM_new_1056ppm_SSS_d18Ow_monthly_T = np.sqrt(np.diag(cov_prior_HadCM_new_1056ppm_SSS_d18Ow_monthly_T))
std_prior_HadCM_old_2PIC_SSS_d18Ow_monthly_T = np.sqrt(np.diag(cov_prior_HadCM_old_2PIC_SSS_d18Ow_monthly_T))
std_prior_HadCM_old_4PIC_SSS_d18Ow_monthly_T = np.sqrt(np.diag(cov_prior_HadCM_old_4PIC_SSS_d18Ow_monthly_T))
std_likelihood_T = np.sqrt(np.diag(cov_likelihood_T))
std_post_CESM_4PIC_SST_D47_T = np.sqrt(np.diag(cov_post_CESM_4PIC_SST_D47_T))
std_post_CESM_2PIC_SST_D47_T = np.sqrt(np.diag(cov_post_CESM_2PIC_SST_D47_T))
std_post_HadCM_new_1PIC_SST_D47_T = np.sqrt(np.diag(cov_post_HadCM_new_1PIC_SST_D47_T))
std_post_HadCM_new_2PIC_SST_D47_T = np.sqrt(np.diag(cov_post_HadCM_new_2PIC_SST_D47_T))
std_post_HadCM_new_1056ppm_SST_D47_T = np.sqrt(np.diag(cov_post_HadCM_new_1056ppm_SST_D47_T))
std_post_HadCM_old_2PIC_SST_D47_T = np.sqrt(np.diag(cov_post_HadCM_old_2PIC_SST_D47_T))
std_post_HadCM_old_4PIC_SST_D47_T = np.sqrt(np.diag(cov_post_HadCM_old_4PIC_SST_D47_T))
std_post_CESM_4PIC_SSS_d18Ow_T = np.sqrt(np.diag(cov_post_CESM_4PIC_SSS_d18Ow_T))
std_post_CESM_2PIC_SSS_d18Ow_T = np.sqrt(np.diag(cov_post_CESM_2PIC_SSS_d18Ow_T))
std_post_HadCM_new_1PIC_SSS_d18Ow_T = np.sqrt(np.diag(cov_post_HadCM_new_1PIC_SSS_d18Ow_T))
std_post_HadCM_new_2PIC_SSS_d18Ow_T = np.sqrt(np.diag(cov_post_HadCM_new_2PIC_SSS_d18Ow_T))
std_post_HadCM_new_1056ppm_SSS_d18Ow_T = np.sqrt(np.diag(cov_post_HadCM_new_1056ppm_SSS_d18Ow_T))
std_post_HadCM_old_2PIC_SSS_d18Ow_T = np.sqrt(np.diag(cov_post_HadCM_old_2PIC_SSS_d18Ow_T))
std_post_HadCM_old_4PIC_SSS_d18Ow_T = np.sqrt(np.diag(cov_post_HadCM_old_4PIC_SSS_d18Ow_T))
Plot SST and SSS prior and posterior¶
In [77]:
# Initiate plot
fig, axs = plt.subplots(2, 7, figsize=(20, 8), sharex="col", sharey="row")
# Start with DA based on CESM model outcomes with 4x preindustrial pCO2 forcing
# FIRST PANEL: SST Results
# PRIOR
axs[0, 0].plot(months_scale, mu_prior_CESM_4PIC_SST_D47_monthly_T, label='Prior Mean', color='b', marker='o')
axs[0, 0].fill_between(months_scale,
mu_prior_CESM_4PIC_SST_D47_monthly_T - stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SST_D47_monthly_T / np.sqrt(n_models_CESM_4PIC_monthly),
mu_prior_CESM_4PIC_SST_D47_monthly_T + stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SST_D47_monthly_T / np.sqrt(n_models_CESM_4PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[0, 0].plot(months_scale, mu_likelihood_T, label='Likelihood Mean', color='y', marker='o')
axs[0, 0].fill_between(months_scale,
mu_likelihood_T - stats.t.ppf(1 - 0.025, n_update_CESM_4PIC_D47) * std_likelihood_T / np.sqrt(n_update_CESM_4PIC_D47),
mu_likelihood_T + stats.t.ppf(1 - 0.025, n_update_CESM_4PIC_D47) * std_likelihood_T / np.sqrt(n_update_CESM_4PIC_D47),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[0, 0].plot(months_scale, mu_post_CESM_4PIC_SST_D47_T, label='Posterior Mean', color='r', marker='o')
axs[0, 0].fill_between(months_scale,
mu_post_CESM_4PIC_SST_D47_T - stats.t.ppf(1 - 0.025, (n_update_CESM_4PIC_D47 + n_models_CESM_4PIC_monthly)) * std_post_CESM_4PIC_SST_D47_T / np.sqrt(n_update_CESM_4PIC_D47 + n_models_CESM_4PIC_monthly),
mu_post_CESM_4PIC_SST_D47_T + stats.t.ppf(1 - 0.025, (n_update_CESM_4PIC_D47 + n_models_CESM_4PIC_monthly)) * std_post_CESM_4PIC_SST_D47_T / np.sqrt(n_update_CESM_4PIC_D47 + n_models_CESM_4PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SST panel
axs[0, 0].set_title('CESM 4x preindustrial pCO2')
axs[0, 0].set_xlabel('Month')
axs[0, 0].set_ylabel('Temperature (°C)')
# axs[0, 0].legend(loc='upper left')
axs[0, 0].grid(True)
axs[0, 0].set_xticks(months_scale, month_names, rotation=45, ha="right")
# SECOND PANEL: SSS Results
# PRIOR
axs[1, 0].plot(months_scale, mu_prior_CESM_4PIC_SSS_d18Ow_monthly_T, label='Prior Mean', color='b', marker='o')
axs[1, 0].fill_between(months_scale,
mu_prior_CESM_4PIC_SSS_d18Ow_monthly_T - stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SSS_d18Ow_monthly_T / np.sqrt(n_models_CESM_4PIC_monthly),
mu_prior_CESM_4PIC_SSS_d18Ow_monthly_T + stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SSS_d18Ow_monthly_T / np.sqrt(n_models_CESM_4PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[1, 0].plot(months_scale, mu_likelihood_SSS_d18Ow_T, label='Likelihood Mean', color='y', marker='o')
axs[1, 0].fill_between(months_scale,
mu_likelihood_SSS_d18Ow_T - stats.t.ppf(1 - 0.025, n_update_CESM_4PIC_d18Oc) * std_likelihood_SSS_d18Ow_T / np.sqrt(n_update_CESM_4PIC_d18Oc),
mu_likelihood_SSS_d18Ow_T + stats.t.ppf(1 - 0.025, n_update_CESM_4PIC_d18Oc) * std_likelihood_SSS_d18Ow_T / np.sqrt(n_update_CESM_4PIC_d18Oc),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[1, 0].plot(months_scale, mu_post_CESM_4PIC_SSS_d18Ow_T, label='Posterior Mean', color='r', marker='o')
axs[1, 0].fill_between(months_scale,
mu_post_CESM_4PIC_SSS_d18Ow_T - stats.t.ppf(1 - 0.025, (n_update_CESM_4PIC_d18Oc + n_models_CESM_4PIC_monthly)) * std_post_CESM_4PIC_SSS_d18Ow_T / np.sqrt(n_update_CESM_4PIC_d18Oc + n_models_CESM_4PIC_monthly),
mu_post_CESM_4PIC_SSS_d18Ow_T + stats.t.ppf(1 - 0.025, (n_update_CESM_4PIC_d18Oc + n_models_CESM_4PIC_monthly)) * std_post_CESM_4PIC_SSS_d18Ow_T / np.sqrt(n_update_CESM_4PIC_d18Oc + n_models_CESM_4PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SSS panel
# axs[1, 0].set_title('monthly Sea Surface Salinity (SSS)')
axs[1, 0].set_xlabel('Month')
axs[1, 0].set_ylabel('Salinity (PSU)')
# axs[1, 0].legend(loc='upper left')
axs[1, 0].grid(True)
axs[1, 0].set_xticks(months_scale, month_names, rotation=45, ha="right")
# Next panels similar but for CESM with 2x preindustrial pCO2 forcing
# FIRST PANEL: SST Results for 2x pCO2
# PRIOR
axs[0, 1].plot(months_scale, mu_prior_CESM_2PIC_SST_D47_monthly_T, label='Prior Mean', color='b', marker='o')
axs[0, 1].fill_between(months_scale,
mu_prior_CESM_2PIC_SST_D47_monthly_T - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SST_D47_monthly_T / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_SST_D47_monthly_T + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SST_D47_monthly_T / np.sqrt(n_models_CESM_2PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[0, 1].plot(months_scale, mu_likelihood_T, label='Likelihood Mean', color='y', marker='o')
axs[0, 1].fill_between(months_scale,
mu_likelihood_T - stats.t.ppf(1 - 0.025, n_update_CESM_2PIC_D47) * std_likelihood_T / np.sqrt(n_update_CESM_2PIC_D47),
mu_likelihood_T + stats.t.ppf(1 - 0.025, n_update_CESM_2PIC_D47) * std_likelihood_T / np.sqrt(n_update_CESM_2PIC_D47),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[0, 1].plot(months_scale, mu_post_CESM_2PIC_SST_D47_T, label='Posterior Mean', color='r', marker='o')
axs[0, 1].fill_between(months_scale,
mu_post_CESM_2PIC_SST_D47_T - stats.t.ppf(1 - 0.025, (n_update_CESM_2PIC_D47 + n_models_CESM_2PIC_monthly)) * std_post_CESM_2PIC_SST_D47_T / np.sqrt(n_update_CESM_2PIC_D47 + n_models_CESM_2PIC_monthly),
mu_post_CESM_2PIC_SST_D47_T + stats.t.ppf(1 - 0.025, (n_update_CESM_2PIC_D47 + n_models_CESM_2PIC_monthly)) * std_post_CESM_2PIC_SST_D47_T / np.sqrt(n_update_CESM_2PIC_D47 + n_models_CESM_2PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SST panel
axs[0, 1].set_title('CESM 2x preindustrial pCO2')
axs[0, 1].set_xlabel('Month')
axs[0, 1].set_ylabel('Temperature (°C)')
# axs[0, 1].legend(loc='upper left')
axs[0, 1].grid(True)
axs[0, 1].set_xticks(months_scale, month_names, rotation=45, ha="right")
# FOURTH PANEL: SSS Results for 2x pCO2
# PRIOR
axs[1, 1].plot(months_scale, mu_prior_CESM_2PIC_SSS_d18Ow_monthly_T, label='Prior Mean', color='b', marker='o')
axs[1, 1].fill_between(months_scale,
mu_prior_CESM_2PIC_SSS_d18Ow_monthly_T - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SSS_d18Ow_monthly_T / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_SSS_d18Ow_monthly_T + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SSS_d18Ow_monthly_T / np.sqrt(n_models_CESM_2PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[1, 1].plot(months_scale, mu_likelihood_SSS_d18Ow_T, label='Likelihood Mean', color='y', marker='o')
axs[1, 1].fill_between(months_scale,
mu_likelihood_SSS_d18Ow_T - stats.t.ppf(1 - 0.025, n_update_CESM_2PIC_d18Oc) * std_likelihood_SSS_d18Ow_T / np.sqrt(n_update_CESM_2PIC_d18Oc),
mu_likelihood_SSS_d18Ow_T + stats.t.ppf(1 - 0.025, n_update_CESM_2PIC_d18Oc) * std_likelihood_SSS_d18Ow_T / np.sqrt(n_update_CESM_2PIC_d18Oc),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[1, 1].plot(months_scale, mu_post_CESM_2PIC_SSS_d18Ow_T, label='Posterior Mean', color='r', marker='o')
axs[1, 1].fill_between(months_scale,
mu_post_CESM_2PIC_SSS_d18Ow_T - stats.t.ppf(1 - 0.025, (n_update_CESM_2PIC_d18Oc + n_models_CESM_2PIC_monthly)) * std_post_CESM_2PIC_SSS_d18Ow_T / np.sqrt(n_update_CESM_2PIC_d18Oc + n_models_CESM_2PIC_monthly),
mu_post_CESM_2PIC_SSS_d18Ow_T + stats.t.ppf(1 - 0.025, (n_update_CESM_2PIC_d18Oc + n_models_CESM_2PIC_monthly)) * std_post_CESM_2PIC_SSS_d18Ow_T / np.sqrt(n_update_CESM_2PIC_d18Oc + n_models_CESM_2PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SSS panel
# axs[1, 1].set_title('monthly Sea Surface Salinity (SSS)')
axs[1, 1].set_xlabel('Month')
axs[1, 1].set_ylabel('Salinity (PSU)')
# axs[1, 1].legend(loc='upper left')
axs[1, 1].grid(True)
axs[1, 1].set_xticks(months_scale, month_names, rotation=45, ha="right")
# Next panels similar but for HadCM (new) with 1x preindustrial pCO2 forcing
# SST Results for 2x pCO2
# PRIOR
axs[0, 2].plot(months_scale, mu_prior_HadCM_new_1PIC_SST_D47_monthly_T, label='Prior Mean', color='b', marker='o')
axs[0, 2].fill_between(months_scale,
mu_prior_HadCM_new_1PIC_SST_D47_monthly_T - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SST_D47_monthly_T / np.sqrt(n_models_HadCM_new_1PIC_monthly),
mu_prior_HadCM_new_1PIC_SST_D47_monthly_T + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SST_D47_monthly_T / np.sqrt(n_models_HadCM_new_1PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[0, 2].plot(months_scale, mu_likelihood_T, label='Likelihood Mean', color='y', marker='o')
axs[0, 2].fill_between(months_scale,
mu_likelihood_T - stats.t.ppf(1 - 0.025, n_update_HadCM_new_1PIC_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_new_1PIC_D47),
mu_likelihood_T + stats.t.ppf(1 - 0.025, n_update_HadCM_new_1PIC_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_new_1PIC_D47),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[0, 2].plot(months_scale, mu_post_HadCM_new_1PIC_SST_D47_T, label='Posterior Mean', color='r', marker='o')
axs[0, 2].fill_between(months_scale,
mu_post_HadCM_new_1PIC_SST_D47_T - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1PIC_D47 + n_models_HadCM_new_1PIC_monthly)) * std_post_HadCM_new_1PIC_SST_D47_T / np.sqrt(n_update_HadCM_new_1PIC_D47 + n_models_HadCM_new_1PIC_monthly),
mu_post_HadCM_new_1PIC_SST_D47_T + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1PIC_D47 + n_models_HadCM_new_1PIC_monthly)) * std_post_HadCM_new_1PIC_SST_D47_T / np.sqrt(n_update_HadCM_new_1PIC_D47 + n_models_HadCM_new_1PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SST panel
axs[0, 2].set_title('HadCM 1x preindustrial pCO2')
axs[0, 2].set_xlabel('Month')
axs[0, 2].set_ylabel('Temperature (°C)')
# axs[0, 2].legend(loc='upper left')
axs[0, 2].grid(True)
axs[0, 2].set_xticks(months_scale, month_names, rotation=45, ha="right")
# SSS Results for 2x pCO2
# PRIOR
axs[1, 2].plot(months_scale, mu_prior_HadCM_new_1PIC_SSS_d18Ow_monthly_T, label='Prior Mean', color='b', marker='o')
axs[1, 2].fill_between(months_scale,
mu_prior_HadCM_new_1PIC_SSS_d18Ow_monthly_T - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SSS_d18Ow_monthly_T / np.sqrt(n_models_HadCM_new_1PIC_monthly),
mu_prior_HadCM_new_1PIC_SSS_d18Ow_monthly_T + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SSS_d18Ow_monthly_T / np.sqrt(n_models_HadCM_new_1PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[1, 2].plot(months_scale, mu_likelihood_SSS_d18Ow_T, label='Likelihood Mean', color='y', marker='o')
axs[1, 2].fill_between(months_scale,
mu_likelihood_SSS_d18Ow_T - stats.t.ppf(1 - 0.025, n_update_HadCM_new_1PIC_d18Oc) * std_likelihood_SSS_d18Ow_T / np.sqrt(n_update_HadCM_new_1PIC_d18Oc),
mu_likelihood_SSS_d18Ow_T + stats.t.ppf(1 - 0.025, n_update_HadCM_new_1PIC_d18Oc) * std_likelihood_SSS_d18Ow_T / np.sqrt(n_update_HadCM_new_1PIC_d18Oc),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[1, 2].plot(months_scale, mu_post_HadCM_new_1PIC_SSS_d18Ow_T, label='Posterior Mean', color='r', marker='o')
axs[1, 2].fill_between(months_scale,
mu_post_HadCM_new_1PIC_SSS_d18Ow_T - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1PIC_d18Oc + n_models_HadCM_new_1PIC_monthly)) * std_post_HadCM_new_1PIC_SSS_d18Ow_T / np.sqrt(n_update_HadCM_new_1PIC_d18Oc + n_models_HadCM_new_1PIC_monthly),
mu_post_HadCM_new_1PIC_SSS_d18Ow_T + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1PIC_d18Oc + n_models_HadCM_new_1PIC_monthly)) * std_post_HadCM_new_1PIC_SSS_d18Ow_T / np.sqrt(n_update_HadCM_new_1PIC_d18Oc + n_models_HadCM_new_1PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SSS panel
# axs[1, 2].set_title('monthly Sea Surface Salinity (SSS)')
axs[1, 2].set_xlabel('Month')
axs[1, 2].set_ylabel('Salinity (PSU)')
# axs[1, 2].legend(loc='upper left')
axs[1, 2].grid(True)
axs[1, 2].set_xticks(months_scale, month_names, rotation=45, ha="right")
# Next panels similar but for HadCM (new) with 2x preindustrial pCO2 forcing
# SST Results for 2x pCO2
# PRIOR
axs[0, 3].plot(months_scale, mu_prior_HadCM_new_2PIC_SST_D47_monthly_T, label='Prior Mean', color='b', marker='o')
axs[0, 3].fill_between(months_scale,
mu_prior_HadCM_new_2PIC_SST_D47_monthly_T - stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SST_D47_monthly_T / np.sqrt(n_models_HadCM_new_2PIC_monthly),
mu_prior_HadCM_new_2PIC_SST_D47_monthly_T + stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SST_D47_monthly_T / np.sqrt(n_models_HadCM_new_2PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[0, 3].plot(months_scale, mu_likelihood_T, label='Likelihood Mean', color='y', marker='o')
axs[0, 3].fill_between(months_scale,
mu_likelihood_T - stats.t.ppf(1 - 0.025, n_update_HadCM_new_2PIC_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_new_2PIC_D47),
mu_likelihood_T + stats.t.ppf(1 - 0.025, n_update_HadCM_new_2PIC_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_new_2PIC_D47),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[0, 3].plot(months_scale, mu_post_HadCM_new_2PIC_SST_D47_T, label='Posterior Mean', color='r', marker='o')
axs[0, 3].fill_between(months_scale,
mu_post_HadCM_new_2PIC_SST_D47_T - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_2PIC_D47 + n_models_HadCM_new_2PIC_monthly)) * std_post_HadCM_new_2PIC_SST_D47_T / np.sqrt(n_update_HadCM_new_2PIC_D47 + n_models_HadCM_new_2PIC_monthly),
mu_post_HadCM_new_2PIC_SST_D47_T + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_2PIC_D47 + n_models_HadCM_new_2PIC_monthly)) * std_post_HadCM_new_2PIC_SST_D47_T / np.sqrt(n_update_HadCM_new_2PIC_D47 + n_models_HadCM_new_2PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SST panel
axs[0, 3].set_title('HadCM 2x preindustrial pCO2')
axs[0, 3].set_xlabel('Month')
axs[0, 3].set_ylabel('Temperature (°C)')
# axs[0, 3].legend(loc='upper left')
axs[0, 3].grid(True)
axs[0, 3].set_xticks(months_scale, month_names, rotation=45, ha="right")
# SSS Results for 2x pCO2
# PRIOR
axs[1, 3].plot(months_scale, mu_prior_HadCM_new_2PIC_SSS_d18Ow_monthly_T, label='Prior Mean', color='b', marker='o')
axs[1, 3].fill_between(months_scale,
mu_prior_HadCM_new_2PIC_SSS_d18Ow_monthly_T - stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SSS_d18Ow_monthly_T / np.sqrt(n_models_HadCM_new_2PIC_monthly),
mu_prior_HadCM_new_2PIC_SSS_d18Ow_monthly_T + stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SSS_d18Ow_monthly_T / np.sqrt(n_models_HadCM_new_2PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[1, 3].plot(months_scale, mu_likelihood_SSS_d18Ow_T, label='Likelihood Mean', color='y', marker='o')
axs[1, 3].fill_between(months_scale,
mu_likelihood_SSS_d18Ow_T - stats.t.ppf(1 - 0.025, n_update_HadCM_new_2PIC_d18Oc) * std_likelihood_SSS_d18Ow_T / np.sqrt(n_update_HadCM_new_2PIC_d18Oc),
mu_likelihood_SSS_d18Ow_T + stats.t.ppf(1 - 0.025, n_update_HadCM_new_2PIC_d18Oc) * std_likelihood_SSS_d18Ow_T / np.sqrt(n_update_HadCM_new_2PIC_d18Oc),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[1, 3].plot(months_scale, mu_post_HadCM_new_2PIC_SSS_d18Ow_T, label='Posterior Mean', color='r', marker='o')
axs[1, 3].fill_between(months_scale,
mu_post_HadCM_new_2PIC_SSS_d18Ow_T - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_2PIC_d18Oc + n_models_HadCM_new_2PIC_monthly)) * std_post_HadCM_new_2PIC_SSS_d18Ow_T / np.sqrt(n_update_HadCM_new_2PIC_d18Oc + n_models_HadCM_new_2PIC_monthly),
mu_post_HadCM_new_2PIC_SSS_d18Ow_T + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_2PIC_d18Oc + n_models_HadCM_new_2PIC_monthly)) * std_post_HadCM_new_2PIC_SSS_d18Ow_T / np.sqrt(n_update_HadCM_new_2PIC_d18Oc + n_models_HadCM_new_2PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SSS panel
# axs[1, 3].set_title('monthly Sea Surface Salinity (SSS)')
axs[1, 3].set_xlabel('Month')
axs[1, 3].set_ylabel('Salinity (PSU)')
# axs[1, 3].legend(loc='upper left')
axs[1, 3].grid(True)
axs[1, 3].set_xticks(months_scale, month_names, rotation=45, ha="right")
# Next panels similar but for HadCM (new) with 1056 ppm pCO2 forcing
# SST Results for 2x pCO2
# PRIOR
axs[0, 4].plot(months_scale, mu_prior_HadCM_new_1056ppm_SST_D47_monthly_T, label='Prior Mean', color='b', marker='o')
axs[0, 4].fill_between(months_scale,
mu_prior_HadCM_new_1056ppm_SST_D47_monthly_T - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SST_D47_monthly_T / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
mu_prior_HadCM_new_1056ppm_SST_D47_monthly_T + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SST_D47_monthly_T / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[0, 4].plot(months_scale, mu_likelihood_T, label='Likelihood Mean', color='y', marker='o')
axs[0, 4].fill_between(months_scale,
mu_likelihood_T - stats.t.ppf(1 - 0.025, n_update_HadCM_new_1056ppm_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_new_1056ppm_D47),
mu_likelihood_T + stats.t.ppf(1 - 0.025, n_update_HadCM_new_1056ppm_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_new_1056ppm_D47),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[0, 4].plot(months_scale, mu_post_HadCM_new_1056ppm_SST_D47_T, label='Posterior Mean', color='r', marker='o')
axs[0, 4].fill_between(months_scale,
mu_post_HadCM_new_1056ppm_SST_D47_T - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1056ppm_D47 + n_models_HadCM_new_1056ppm_monthly)) * std_post_HadCM_new_1056ppm_SST_D47_T / np.sqrt(n_update_HadCM_new_1056ppm_D47 + n_models_HadCM_new_1056ppm_monthly),
mu_post_HadCM_new_1056ppm_SST_D47_T + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1056ppm_D47 + n_models_HadCM_new_1056ppm_monthly)) * std_post_HadCM_new_1056ppm_SST_D47_T / np.sqrt(n_update_HadCM_new_1056ppm_D47 + n_models_HadCM_new_1056ppm_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SST panel
axs[0, 4].set_title('HadCM (new) 1056 ppm pCO2')
axs[0, 4].set_xlabel('Month')
axs[0, 4].set_ylabel('Temperature (°C)')
# axs[0, 4].legend(loc='upper left')
axs[0, 4].grid(True)
axs[0, 4].set_xticks(months_scale, month_names, rotation=45, ha="right")
# SSS Results for 2x pCO2
# PRIOR
axs[1, 4].plot(months_scale, mu_prior_HadCM_new_1056ppm_SSS_d18Ow_monthly_T, label='Prior Mean', color='b', marker='o')
axs[1, 4].fill_between(months_scale,
mu_prior_HadCM_new_1056ppm_SSS_d18Ow_monthly_T - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SSS_d18Ow_monthly_T / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
mu_prior_HadCM_new_1056ppm_SSS_d18Ow_monthly_T + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SSS_d18Ow_monthly_T / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[1, 4].plot(months_scale, mu_likelihood_SSS_d18Ow_T, label='Likelihood Mean', color='y', marker='o')
axs[1, 4].fill_between(months_scale,
mu_likelihood_SSS_d18Ow_T - stats.t.ppf(1 - 0.025, n_update_HadCM_new_1056ppm_d18Oc) * std_likelihood_SSS_d18Ow_T / np.sqrt(n_update_HadCM_new_1056ppm_d18Oc),
mu_likelihood_SSS_d18Ow_T + stats.t.ppf(1 - 0.025, n_update_HadCM_new_1056ppm_d18Oc) * std_likelihood_SSS_d18Ow_T / np.sqrt(n_update_HadCM_new_1056ppm_d18Oc),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[1, 4].plot(months_scale, mu_post_HadCM_new_1056ppm_SSS_d18Ow_T, label='Posterior Mean', color='r', marker='o')
axs[1, 4].fill_between(months_scale,
mu_post_HadCM_new_1056ppm_SSS_d18Ow_T - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1056ppm_d18Oc + n_models_HadCM_new_1056ppm_monthly)) * std_post_HadCM_new_1056ppm_SSS_d18Ow_T / np.sqrt(n_update_HadCM_new_1056ppm_d18Oc + n_models_HadCM_new_1056ppm_monthly),
mu_post_HadCM_new_1056ppm_SSS_d18Ow_T + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1056ppm_d18Oc + n_models_HadCM_new_1056ppm_monthly)) * std_post_HadCM_new_1056ppm_SSS_d18Ow_T / np.sqrt(n_update_HadCM_new_1056ppm_d18Oc + n_models_HadCM_new_1056ppm_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SSS panel
# axs[1, 4].set_title('monthly Sea Surface Salinity (SSS)')
axs[1, 4].set_xlabel('Month')
axs[1, 4].set_ylabel('Salinity (PSU)')
# axs[1, 4].legend(loc='upper left')
axs[1, 4].grid(True)
axs[1, 4].set_xticks(months_scale, month_names, rotation=45, ha="right")
# Next panels similar but for HadCM (old) with 2x preindustrial pCO2 forcing
# SST Results for 2x pCO2
# PRIOR
axs[0, 5].plot(months_scale, mu_prior_HadCM_old_2PIC_SST_D47_monthly_T, label='Prior Mean', color='b', marker='o')
axs[0, 5].fill_between(months_scale,
mu_prior_HadCM_old_2PIC_SST_D47_monthly_T - stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SST_D47_monthly_T / np.sqrt(n_models_HadCM_old_2PIC_monthly),
mu_prior_HadCM_old_2PIC_SST_D47_monthly_T + stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SST_D47_monthly_T / np.sqrt(n_models_HadCM_old_2PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[0, 5].plot(months_scale, mu_likelihood_T, label='Likelihood Mean', color='y', marker='o')
axs[0, 5].fill_between(months_scale,
mu_likelihood_T - stats.t.ppf(1 - 0.025, n_update_HadCM_old_2PIC_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_old_2PIC_D47),
mu_likelihood_T + stats.t.ppf(1 - 0.025, n_update_HadCM_old_2PIC_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_old_2PIC_D47),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[0, 5].plot(months_scale, mu_post_HadCM_old_2PIC_SST_D47_T, label='Posterior Mean', color='r', marker='o')
axs[0, 5].fill_between(months_scale,
mu_post_HadCM_old_2PIC_SST_D47_T - stats.t.ppf(1 - 0.025, (n_update_HadCM_old_2PIC_D47 + n_models_HadCM_old_2PIC_monthly)) * std_post_HadCM_old_2PIC_SST_D47_T / np.sqrt(n_update_HadCM_old_2PIC_D47 + n_models_HadCM_old_2PIC_monthly),
mu_post_HadCM_old_2PIC_SST_D47_T + stats.t.ppf(1 - 0.025, (n_update_HadCM_old_2PIC_D47 + n_models_HadCM_old_2PIC_monthly)) * std_post_HadCM_old_2PIC_SST_D47_T / np.sqrt(n_update_HadCM_old_2PIC_D47 + n_models_HadCM_old_2PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SST panel
axs[0, 5].set_title('HadCM (old) 2x preindustrial pCO2')
axs[0, 5].set_xlabel('Month')
axs[0, 5].set_ylabel('Temperature (°C)')
# axs[0, 5].legend(loc='upper left')
axs[0, 5].grid(True)
axs[0, 5].set_xticks(months_scale, month_names, rotation=45, ha="right")
# SSS Results for 2x pCO2
# PRIOR
axs[1, 5].plot(months_scale, mu_prior_HadCM_old_2PIC_SSS_d18Ow_monthly_T, label='Prior Mean', color='b', marker='o')
axs[1, 5].fill_between(months_scale,
mu_prior_HadCM_old_2PIC_SSS_d18Ow_monthly_T - stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SSS_d18Ow_monthly_T / np.sqrt(n_models_HadCM_old_2PIC_monthly),
mu_prior_HadCM_old_2PIC_SSS_d18Ow_monthly_T + stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SSS_d18Ow_monthly_T / np.sqrt(n_models_HadCM_old_2PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[1, 5].plot(months_scale, mu_likelihood_SSS_d18Ow_T, label='Likelihood Mean', color='y', marker='o')
axs[1, 5].fill_between(months_scale,
mu_likelihood_SSS_d18Ow_T - stats.t.ppf(1 - 0.025, n_update_HadCM_old_2PIC_d18Oc) * std_likelihood_SSS_d18Ow_T / np.sqrt(n_update_HadCM_old_2PIC_d18Oc),
mu_likelihood_SSS_d18Ow_T + stats.t.ppf(1 - 0.025, n_update_HadCM_old_2PIC_d18Oc) * std_likelihood_SSS_d18Ow_T / np.sqrt(n_update_HadCM_old_2PIC_d18Oc),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[1, 5].plot(months_scale, mu_post_HadCM_old_2PIC_SSS_d18Ow_T, label='Posterior Mean', color='r', marker='o')
axs[1, 5].fill_between(months_scale,
mu_post_HadCM_old_2PIC_SSS_d18Ow_T - stats.t.ppf(1 - 0.025, (n_update_HadCM_old_2PIC_d18Oc + n_models_HadCM_old_2PIC_monthly)) * std_post_HadCM_old_2PIC_SSS_d18Ow_T / np.sqrt(n_update_HadCM_old_2PIC_d18Oc + n_models_HadCM_old_2PIC_monthly),
mu_post_HadCM_old_2PIC_SSS_d18Ow_T + stats.t.ppf(1 - 0.025, (n_update_HadCM_old_2PIC_d18Oc + n_models_HadCM_old_2PIC_monthly)) * std_post_HadCM_old_2PIC_SSS_d18Ow_T / np.sqrt(n_update_HadCM_old_2PIC_d18Oc + n_models_HadCM_old_2PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SSS panel
# axs[1, 5].set_title('monthly Sea Surface Salinity (SSS)')
axs[1, 5].set_xlabel('Month')
axs[1, 5].set_ylabel('Salinity (PSU)')
# axs[1, 5].legend(loc='upper left')
axs[1, 5].grid(True)
axs[1, 5].set_xticks(months_scale, month_names, rotation=45, ha="right")
# Next panels similar but for HadCM (old) with 2x preindustrial pCO2 forcing
# SST Results for 2x pCO2
# PRIOR
axs[0, 6].plot(months_scale, mu_prior_HadCM_old_4PIC_SST_D47_monthly_T, label='Prior Mean', color='b', marker='o')
axs[0, 6].fill_between(months_scale,
mu_prior_HadCM_old_4PIC_SST_D47_monthly_T - stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SST_D47_monthly_T / np.sqrt(n_models_HadCM_old_4PIC_monthly),
mu_prior_HadCM_old_4PIC_SST_D47_monthly_T + stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SST_D47_monthly_T / np.sqrt(n_models_HadCM_old_4PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[0, 6].plot(months_scale, mu_likelihood_T, label='Likelihood Mean', color='y', marker='o')
axs[0, 6].fill_between(months_scale,
mu_likelihood_T - stats.t.ppf(1 - 0.025, n_update_HadCM_old_4PIC_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_old_4PIC_D47),
mu_likelihood_T + stats.t.ppf(1 - 0.025, n_update_HadCM_old_4PIC_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_old_4PIC_D47),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[0, 6].plot(months_scale, mu_post_HadCM_old_4PIC_SST_D47_T, label='Posterior Mean', color='r', marker='o')
axs[0, 6].fill_between(months_scale,
mu_post_HadCM_old_4PIC_SST_D47_T - stats.t.ppf(1 - 0.025, (n_update_HadCM_old_4PIC_D47 + n_models_HadCM_old_4PIC_monthly)) * std_post_HadCM_old_4PIC_SST_D47_T / np.sqrt(n_update_HadCM_old_4PIC_D47 + n_models_HadCM_old_4PIC_monthly),
mu_post_HadCM_old_4PIC_SST_D47_T + stats.t.ppf(1 - 0.025, (n_update_HadCM_old_4PIC_D47 + n_models_HadCM_old_4PIC_monthly)) * std_post_HadCM_old_4PIC_SST_D47_T / np.sqrt(n_update_HadCM_old_4PIC_D47 + n_models_HadCM_old_4PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SST panel
axs[0, 6].set_title('HadCM (old) 4x preindustrial pCO2')
axs[0, 6].set_xlabel('Month')
axs[0, 6].set_ylabel('Temperature (°C)')
axs[0, 6].legend(loc='upper left')
axs[0, 6].grid(True)
axs[0, 6].set_xticks(months_scale, month_names, rotation=45, ha="right")
# SSS Results for 2x pCO2
# PRIOR
axs[1, 6].plot(months_scale, mu_prior_HadCM_old_4PIC_SSS_d18Ow_monthly_T, label='Prior Mean', color='b', marker='o')
axs[1, 6].fill_between(months_scale,
mu_prior_HadCM_old_4PIC_SSS_d18Ow_monthly_T - stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SSS_d18Ow_monthly_T / np.sqrt(n_models_HadCM_old_4PIC_monthly),
mu_prior_HadCM_old_4PIC_SSS_d18Ow_monthly_T + stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SSS_d18Ow_monthly_T / np.sqrt(n_models_HadCM_old_4PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[1, 6].plot(months_scale, mu_likelihood_SSS_d18Ow_T, label='Likelihood Mean', color='y', marker='o')
axs[1, 6].fill_between(months_scale,
mu_likelihood_SSS_d18Ow_T - stats.t.ppf(1 - 0.025, n_update_HadCM_old_4PIC_d18Oc) * std_likelihood_SSS_d18Ow_T / np.sqrt(n_update_HadCM_old_4PIC_d18Oc),
mu_likelihood_SSS_d18Ow_T + stats.t.ppf(1 - 0.025, n_update_HadCM_old_4PIC_d18Oc) * std_likelihood_SSS_d18Ow_T / np.sqrt(n_update_HadCM_old_4PIC_d18Oc),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[1, 6].plot(months_scale, mu_post_HadCM_old_4PIC_SSS_d18Ow_T, label='Posterior Mean', color='r', marker='o')
axs[1, 6].fill_between(months_scale,
mu_post_HadCM_old_4PIC_SSS_d18Ow_T - stats.t.ppf(1 - 0.025, (n_update_HadCM_old_4PIC_d18Oc + n_models_HadCM_old_4PIC_monthly)) * std_post_HadCM_old_4PIC_SSS_d18Ow_T / np.sqrt(n_update_HadCM_old_4PIC_d18Oc + n_models_HadCM_old_4PIC_monthly),
mu_post_HadCM_old_4PIC_SSS_d18Ow_T + stats.t.ppf(1 - 0.025, (n_update_HadCM_old_4PIC_d18Oc + n_models_HadCM_old_4PIC_monthly)) * std_post_HadCM_old_4PIC_SSS_d18Ow_T / np.sqrt(n_update_HadCM_old_4PIC_d18Oc + n_models_HadCM_old_4PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SSS panel
# axs[1, 6].set_title('monthly Sea Surface Salinity (SSS)')
axs[1, 6].set_xlabel('Month')
axs[1, 6].set_ylabel('Salinity (PSU)')
axs[1, 6].legend(loc='upper left')
axs[1, 6].grid(True)
axs[1, 6].set_xticks(months_scale, month_names, rotation=45, ha="right")
# Shared x-axis labels
plt.xticks(months_scale, month_names, rotation=45, ha="right")
plt.suptitle('Seasonal Sea Surface Temperature (SST) and Sea Surface Salinity (SSS) outcomes for all model scenarios', fontsize=16)
plt.tight_layout()
plt.show()
Execute SAT and precipitation error propagation for all model scenarios¶
In [78]:
# Convert posterior D47 to temp
mu_post_CESM_2PIC_SAT_D47_T = D47c.OGLS23.T47(D47 = mu_post_CESM_2PIC_SAT_D47, sD47 = cov_post_CESM_2PIC_SAT_D47, return_covar = True)[0]
mu_post_CESM_4PIC_SAT_D47_T = D47c.OGLS23.T47(D47 = mu_post_CESM_4PIC_SAT_D47, sD47 = cov_post_CESM_4PIC_SAT_D47, return_covar = True)[0]
mu_post_HadCM_new_1PIC_SAT_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_1PIC_SAT_D47, sD47 = cov_post_HadCM_new_1PIC_SAT_D47, return_covar = True)[0]
mu_post_HadCM_new_2PIC_SAT_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_2PIC_SAT_D47, sD47 = cov_post_HadCM_new_2PIC_SAT_D47, return_covar = True)[0]
mu_post_HadCM_new_1056ppm_SAT_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_1056ppm_SAT_D47, sD47 = cov_post_HadCM_new_1056ppm_SAT_D47, return_covar = True)[0]
mu_post_HadCM_old_2PIC_SAT_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_old_2PIC_SAT_D47, sD47 = cov_post_HadCM_old_2PIC_SAT_D47, return_covar = True)[0]
mu_post_HadCM_old_4PIC_SAT_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_old_4PIC_SAT_D47, sD47 = cov_post_HadCM_old_4PIC_SAT_D47, return_covar = True)[0]
cov_post_CESM_2PIC_SAT_D47_T = D47c.OGLS23.T47(D47 = mu_post_CESM_2PIC_SAT_D47, sD47 = cov_post_CESM_2PIC_SAT_D47, return_covar = True)[1]
cov_post_CESM_4PIC_SAT_D47_T = D47c.OGLS23.T47(D47 = mu_post_CESM_4PIC_SAT_D47, sD47 = cov_post_CESM_4PIC_SAT_D47, return_covar = True)[1]
cov_post_HadCM_new_1PIC_SAT_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_1PIC_SAT_D47, sD47 = cov_post_HadCM_new_1PIC_SAT_D47, return_covar = True)[1]
cov_post_HadCM_new_2PIC_SAT_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_2PIC_SAT_D47, sD47 = cov_post_HadCM_new_2PIC_SAT_D47, return_covar = True)[1]
cov_post_HadCM_new_1056ppm_SAT_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_1056ppm_SAT_D47, sD47 = cov_post_HadCM_new_1056ppm_SAT_D47, return_covar = True)[1]
cov_post_HadCM_old_2PIC_SAT_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_old_2PIC_SAT_D47, sD47 = cov_post_HadCM_old_2PIC_SAT_D47, return_covar = True)[1]
cov_post_HadCM_old_4PIC_SAT_D47_T = D47c.OGLS23.T47(D47 = mu_post_HadCM_old_4PIC_SAT_D47, sD47 = cov_post_HadCM_old_4PIC_SAT_D47, return_covar = True)[1]
# Convert posterior SAT-D47 back to temperature
std_post_CESM_2PIC_SAT_D47_T = np.nan_to_num(np.sqrt(np.diag(cov_post_CESM_2PIC_SAT_D47_T)))
std_post_CESM_4PIC_SAT_D47_T = np.nan_to_num(np.sqrt(np.diag(cov_post_CESM_4PIC_SAT_D47_T)))
std_post_HadCM_new_1PIC_SAT_D47_T = np.nan_to_num(np.sqrt(np.diag(cov_post_HadCM_new_1PIC_SAT_D47_T)))
std_post_HadCM_new_2PIC_SAT_D47_T = np.nan_to_num(np.sqrt(np.diag(cov_post_HadCM_new_2PIC_SAT_D47_T)))
std_post_HadCM_new_1056ppm_SAT_D47_T = np.nan_to_num(np.sqrt(np.diag(cov_post_HadCM_new_1056ppm_SAT_D47_T)))
std_post_HadCM_old_2PIC_SAT_D47_T = np.nan_to_num(np.sqrt(np.diag(cov_post_HadCM_old_2PIC_SAT_D47_T)))
std_post_HadCM_old_4PIC_SAT_D47_T = np.nan_to_num(np.sqrt(np.diag(cov_post_HadCM_old_4PIC_SAT_D47_T)))
# Calculate standard deviations for precipitation posteriors
std_post_CESM_2PIC_precip = np.nan_to_num(np.sqrt(np.diag(cov_post_CESM_2PIC_precip)))
std_post_CESM_4PIC_precip = np.nan_to_num(np.sqrt(np.diag(cov_post_CESM_4PIC_precip)))
std_post_HadCM_new_1PIC_precip = np.nan_to_num(np.sqrt(np.diag(cov_post_HadCM_new_1PIC_precip)))
std_post_HadCM_new_2PIC_precip = np.nan_to_num(np.sqrt(np.diag(cov_post_HadCM_new_2PIC_precip)))
std_post_HadCM_new_1056ppm_precip = np.nan_to_num(np.sqrt(np.diag(cov_post_HadCM_new_1056ppm_precip)))
std_post_HadCM_old_2PIC_precip = np.nan_to_num(np.sqrt(np.diag(cov_post_HadCM_old_2PIC_precip)))
std_post_HadCM_old_4PIC_precip = np.nan_to_num(np.sqrt(np.diag(cov_post_HadCM_old_4PIC_precip)))
Plot SAT and precipitation prior and posterior¶
In [79]:
# Initiate plot
fig, axs = plt.subplots(2, 7, figsize=(20, 8), sharex="col", sharey="row")
# Start with DA based on CESM model outcomes with 4x preindustrial pCO2 forcing
# FIRST PANEL: SAT Results
# PRIOR
axs[0, 0].plot(months_scale, mu_prior_CESM_4PIC_SAT_monthly, label='Prior Mean', color='b', marker='o')
axs[0, 0].fill_between(months_scale,
mu_prior_CESM_4PIC_SAT_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SAT_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
mu_prior_CESM_4PIC_SAT_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_SAT_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[0, 0].plot(months_scale, mu_likelihood_T, label='Likelihood Mean', color='y', marker='o')
axs[0, 0].fill_between(months_scale,
mu_likelihood_T - stats.t.ppf(1 - 0.025, n_update_CESM_4PIC_D47) * std_likelihood_T / np.sqrt(n_update_CESM_4PIC_D47),
mu_likelihood_T + stats.t.ppf(1 - 0.025, n_update_CESM_4PIC_D47) * std_likelihood_T / np.sqrt(n_update_CESM_4PIC_D47),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[0, 0].plot(months_scale, mu_post_CESM_4PIC_SAT_D47_T, label='Posterior Mean', color='r', marker='o')
axs[0, 0].fill_between(months_scale,
mu_post_CESM_4PIC_SAT_D47_T - stats.t.ppf(1 - 0.025, (n_update_CESM_4PIC_D47 + n_models_CESM_4PIC_monthly)) * std_post_CESM_4PIC_SAT_D47_T / np.sqrt(n_update_CESM_4PIC_D47 + n_models_CESM_4PIC_monthly),
mu_post_CESM_4PIC_SAT_D47_T + stats.t.ppf(1 - 0.025, (n_update_CESM_4PIC_D47 + n_models_CESM_4PIC_monthly)) * std_post_CESM_4PIC_SAT_D47_T / np.sqrt(n_update_CESM_4PIC_D47 + n_models_CESM_4PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SAT panel
axs[0, 0].set_title('CESM 4x preindustrial pCO2')
axs[0, 0].set_xlabel('Month')
axs[0, 0].set_ylabel('Surface Air Temperature (°C)')
# axs[0, 0].legend(loc='upper left')
axs[0, 0].grid(True)
axs[0, 0].set_xticks(months_scale, month_names, rotation=45, ha="right")
# SECOND PANEL: precip Results
# PRIOR
axs[1, 0].plot(months_scale, mu_prior_CESM_4PIC_precip_monthly, label='Prior Mean', color='b', marker='o')
axs[1, 0].fill_between(months_scale,
mu_prior_CESM_4PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_precip_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
mu_prior_CESM_4PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_4PIC_monthly) * std_prior_CESM_4PIC_precip_monthly / np.sqrt(n_models_CESM_4PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[1, 0].plot(months_scale, mu_post_CESM_4PIC_precip, label='Posterior Mean', color='r', marker='o')
axs[1, 0].fill_between(months_scale,
mu_post_CESM_4PIC_precip - stats.t.ppf(1 - 0.025, (n_update_CESM_4PIC_d18Oc + n_models_CESM_4PIC_monthly)) * std_post_CESM_4PIC_precip / np.sqrt(n_update_CESM_4PIC_d18Oc + n_models_CESM_4PIC_monthly),
mu_post_CESM_4PIC_precip + stats.t.ppf(1 - 0.025, (n_update_CESM_4PIC_d18Oc + n_models_CESM_4PIC_monthly)) * std_post_CESM_4PIC_precip / np.sqrt(n_update_CESM_4PIC_d18Oc + n_models_CESM_4PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for precip panel
# axs[1, 0].set_title('monthly Sea Surface Salinity (precip)')
axs[1, 0].set_xlabel('Month')
axs[1, 0].set_ylabel('Precipitation (mm/day)')
# axs[1, 0].legend(loc='upper left')
axs[1, 0].grid(True)
axs[1, 0].set_xticks(months_scale, month_names, rotation=45, ha="right")
# Next panels similar but for CESM with 2x preindustrial pCO2 forcing
# FIRST PANEL: SAT Results
# PRIOR
axs[0, 1].plot(months_scale, mu_prior_CESM_2PIC_SAT_monthly, label='Prior Mean', color='b', marker='o')
axs[0, 1].fill_between(months_scale,
mu_prior_CESM_2PIC_SAT_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SAT_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_SAT_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_SAT_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[0, 1].plot(months_scale, mu_likelihood_T, label='Likelihood Mean', color='y', marker='o')
axs[0, 1].fill_between(months_scale,
mu_likelihood_T - stats.t.ppf(1 - 0.025, n_update_CESM_2PIC_D47) * std_likelihood_T / np.sqrt(n_update_CESM_2PIC_D47),
mu_likelihood_T + stats.t.ppf(1 - 0.025, n_update_CESM_2PIC_D47) * std_likelihood_T / np.sqrt(n_update_CESM_2PIC_D47),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[0, 1].plot(months_scale, mu_post_CESM_2PIC_SAT_D47_T, label='Posterior Mean', color='r', marker='o')
axs[0, 1].fill_between(months_scale,
mu_post_CESM_2PIC_SAT_D47_T - stats.t.ppf(1 - 0.025, (n_update_CESM_2PIC_D47 + n_models_CESM_2PIC_monthly)) * std_post_CESM_2PIC_SAT_D47_T / np.sqrt(n_update_CESM_2PIC_D47 + n_models_CESM_2PIC_monthly),
mu_post_CESM_2PIC_SAT_D47_T + stats.t.ppf(1 - 0.025, (n_update_CESM_2PIC_D47 + n_models_CESM_2PIC_monthly)) * std_post_CESM_2PIC_SAT_D47_T / np.sqrt(n_update_CESM_2PIC_D47 + n_models_CESM_2PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SAT panel
axs[0, 1].set_title('CESM 2x preindustrial pCO2')
axs[0, 1].set_xlabel('Month')
axs[0, 1].set_ylabel('Surface Air Temperature (°C)')
# axs[0, 1].legend(loc='upper left')
axs[0, 1].grid(True)
axs[0, 1].set_xticks(months_scale, month_names, rotation=45, ha="right")
# FOURTH PANEL: precip Results
# PRIOR
axs[1, 1].plot(months_scale, mu_prior_CESM_2PIC_precip_monthly, label='Prior Mean', color='b', marker='o')
axs[1, 1].fill_between(months_scale,
mu_prior_CESM_2PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_precip_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
mu_prior_CESM_2PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_CESM_2PIC_monthly) * std_prior_CESM_2PIC_precip_monthly / np.sqrt(n_models_CESM_2PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[1, 1].plot(months_scale, mu_post_CESM_2PIC_precip, label='Posterior Mean', color='r', marker='o')
axs[1, 1].fill_between(months_scale,
mu_post_CESM_2PIC_precip - stats.t.ppf(1 - 0.025, (n_update_CESM_2PIC_d18Oc + n_models_CESM_2PIC_monthly)) * std_post_CESM_2PIC_precip / np.sqrt(n_update_CESM_2PIC_d18Oc + n_models_CESM_2PIC_monthly),
mu_post_CESM_2PIC_precip + stats.t.ppf(1 - 0.025, (n_update_CESM_2PIC_d18Oc + n_models_CESM_2PIC_monthly)) * std_post_CESM_2PIC_precip / np.sqrt(n_update_CESM_2PIC_d18Oc + n_models_CESM_2PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for precip panel
# axs[1, 1].set_title('monthly Sea Surface Salinity (precip)')
axs[1, 1].set_xlabel('Month')
axs[1, 1].set_ylabel('Precipitation (mm/day)')
# axs[1, 1].legend(loc='upper left')
axs[1, 1].grid(True)
axs[1, 1].set_xticks(months_scale, month_names, rotation=45, ha="right")
# Next panels similar but for HadCM (new) with 1x preindustrial pCO2 forcing
# SAT Results
# PRIOR
axs[0, 2].plot(months_scale, mu_prior_HadCM_new_1PIC_SAT_monthly, label='Prior Mean', color='b', marker='o')
axs[0, 2].fill_between(months_scale,
mu_prior_HadCM_new_1PIC_SAT_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SAT_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
mu_prior_HadCM_new_1PIC_SAT_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_SAT_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[0, 2].plot(months_scale, mu_likelihood_T, label='Likelihood Mean', color='y', marker='o')
axs[0, 2].fill_between(months_scale,
mu_likelihood_T - stats.t.ppf(1 - 0.025, n_update_HadCM_new_1PIC_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_new_1PIC_D47),
mu_likelihood_T + stats.t.ppf(1 - 0.025, n_update_HadCM_new_1PIC_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_new_1PIC_D47),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[0, 2].plot(months_scale, mu_post_HadCM_new_1PIC_SAT_D47_T, label='Posterior Mean', color='r', marker='o')
axs[0, 2].fill_between(months_scale,
mu_post_HadCM_new_1PIC_SAT_D47_T - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1PIC_D47 + n_models_HadCM_new_1PIC_monthly)) * std_post_HadCM_new_1PIC_SAT_D47_T / np.sqrt(n_update_HadCM_new_1PIC_D47 + n_models_HadCM_new_1PIC_monthly),
mu_post_HadCM_new_1PIC_SAT_D47_T + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1PIC_D47 + n_models_HadCM_new_1PIC_monthly)) * std_post_HadCM_new_1PIC_SAT_D47_T / np.sqrt(n_update_HadCM_new_1PIC_D47 + n_models_HadCM_new_1PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SAT panel
axs[0, 2].set_title('HadCM 1x preindustrial pCO2')
axs[0, 2].set_xlabel('Month')
axs[0, 2].set_ylabel('Surface Air Temperature (°C)')
# axs[0, 2].legend(loc='upper left')
axs[0, 2].grid(True)
axs[0, 2].set_xticks(months_scale, month_names, rotation=45, ha="right")
# precip Results
# PRIOR
axs[1, 2].plot(months_scale, mu_prior_HadCM_new_1PIC_precip_monthly, label='Prior Mean', color='b', marker='o')
axs[1, 2].fill_between(months_scale,
mu_prior_HadCM_new_1PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_precip_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
mu_prior_HadCM_new_1PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1PIC_monthly) * std_prior_HadCM_new_1PIC_precip_monthly / np.sqrt(n_models_HadCM_new_1PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[1, 2].plot(months_scale, mu_post_HadCM_new_1PIC_precip, label='Posterior Mean', color='r', marker='o')
axs[1, 2].fill_between(months_scale,
mu_post_HadCM_new_1PIC_precip - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1PIC_d18Oc + n_models_HadCM_new_1PIC_monthly)) * std_post_HadCM_new_1PIC_precip / np.sqrt(n_update_HadCM_new_1PIC_d18Oc + n_models_HadCM_new_1PIC_monthly),
mu_post_HadCM_new_1PIC_precip + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1PIC_d18Oc + n_models_HadCM_new_1PIC_monthly)) * std_post_HadCM_new_1PIC_precip / np.sqrt(n_update_HadCM_new_1PIC_d18Oc + n_models_HadCM_new_1PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for precip panel
# axs[1, 2].set_title('monthly Sea Surface Salinity (precip)')
axs[1, 2].set_xlabel('Month')
axs[1, 2].set_ylabel('Precipitation (mm/day)')
# axs[1, 2].legend(loc='upper left')
axs[1, 2].grid(True)
axs[1, 2].set_xticks(months_scale, month_names, rotation=45, ha="right")
# Next panels similar but for HadCM (new) with 2x preindustrial pCO2 forcing
# SAT Results
# PRIOR
axs[0, 3].plot(months_scale, mu_prior_HadCM_new_2PIC_SAT_monthly, label='Prior Mean', color='b', marker='o')
axs[0, 3].fill_between(months_scale,
mu_prior_HadCM_new_2PIC_SAT_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SAT_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
mu_prior_HadCM_new_2PIC_SAT_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_SAT_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[0, 3].plot(months_scale, mu_likelihood_T, label='Likelihood Mean', color='y', marker='o')
axs[0, 3].fill_between(months_scale,
mu_likelihood_T - stats.t.ppf(1 - 0.025, n_update_HadCM_new_2PIC_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_new_2PIC_D47),
mu_likelihood_T + stats.t.ppf(1 - 0.025, n_update_HadCM_new_2PIC_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_new_2PIC_D47),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[0, 3].plot(months_scale, mu_post_HadCM_new_2PIC_SAT_D47_T, label='Posterior Mean', color='r', marker='o')
axs[0, 3].fill_between(months_scale,
mu_post_HadCM_new_2PIC_SAT_D47_T - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_2PIC_D47 + n_models_HadCM_new_2PIC_monthly)) * std_post_HadCM_new_2PIC_SAT_D47_T / np.sqrt(n_update_HadCM_new_2PIC_D47 + n_models_HadCM_new_2PIC_monthly),
mu_post_HadCM_new_2PIC_SAT_D47_T + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_2PIC_D47 + n_models_HadCM_new_2PIC_monthly)) * std_post_HadCM_new_2PIC_SAT_D47_T / np.sqrt(n_update_HadCM_new_2PIC_D47 + n_models_HadCM_new_2PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SAT panel
axs[0, 3].set_title('HadCM 2x preindustrial pCO2')
axs[0, 3].set_xlabel('Month')
axs[0, 3].set_ylabel('Surface Air Temperature (°C)')
# axs[0, 3].legend(loc='upper left')
axs[0, 3].grid(True)
axs[0, 3].set_xticks(months_scale, month_names, rotation=45, ha="right")
# precip Results
# PRIOR
axs[1, 3].plot(months_scale, mu_prior_HadCM_new_2PIC_precip_monthly, label='Prior Mean', color='b', marker='o')
axs[1, 3].fill_between(months_scale,
mu_prior_HadCM_new_2PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_precip_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
mu_prior_HadCM_new_2PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_2PIC_monthly) * std_prior_HadCM_new_2PIC_precip_monthly / np.sqrt(n_models_HadCM_new_2PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[1, 3].plot(months_scale, mu_post_HadCM_new_2PIC_precip, label='Posterior Mean', color='r', marker='o')
axs[1, 3].fill_between(months_scale,
mu_post_HadCM_new_2PIC_precip - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_2PIC_d18Oc + n_models_HadCM_new_2PIC_monthly)) * std_post_HadCM_new_2PIC_precip / np.sqrt(n_update_HadCM_new_2PIC_d18Oc + n_models_HadCM_new_2PIC_monthly),
mu_post_HadCM_new_2PIC_precip + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_2PIC_d18Oc + n_models_HadCM_new_2PIC_monthly)) * std_post_HadCM_new_2PIC_precip / np.sqrt(n_update_HadCM_new_2PIC_d18Oc + n_models_HadCM_new_2PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for precip panel
# axs[1, 3].set_title('monthly Sea Surface Salinity (precip)')
axs[1, 3].set_xlabel('Month')
axs[1, 3].set_ylabel('Precipitation (mm/day)')
# axs[1, 3].legend(loc='upper left')
axs[1, 3].grid(True)
axs[1, 3].set_xticks(months_scale, month_names, rotation=45, ha="right")
# Next panels similar but for HadCM (new) with 1056 ppm pCO2 forcing
# SAT Results
# PRIOR
axs[0, 4].plot(months_scale, mu_prior_HadCM_new_1056ppm_SAT_monthly, label='Prior Mean', color='b', marker='o')
axs[0, 4].fill_between(months_scale,
mu_prior_HadCM_new_1056ppm_SAT_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SAT_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
mu_prior_HadCM_new_1056ppm_SAT_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_SAT_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[0, 4].plot(months_scale, mu_likelihood_T, label='Likelihood Mean', color='y', marker='o')
axs[0, 4].fill_between(months_scale,
mu_likelihood_T - stats.t.ppf(1 - 0.025, n_update_HadCM_new_1056ppm_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_new_1056ppm_D47),
mu_likelihood_T + stats.t.ppf(1 - 0.025, n_update_HadCM_new_1056ppm_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_new_1056ppm_D47),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[0, 4].plot(months_scale, mu_post_HadCM_new_1056ppm_SAT_D47_T, label='Posterior Mean', color='r', marker='o')
axs[0, 4].fill_between(months_scale,
mu_post_HadCM_new_1056ppm_SAT_D47_T - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1056ppm_D47 + n_models_HadCM_new_1056ppm_monthly)) * std_post_HadCM_new_1056ppm_SAT_D47_T / np.sqrt(n_update_HadCM_new_1056ppm_D47 + n_models_HadCM_new_1056ppm_monthly),
mu_post_HadCM_new_1056ppm_SAT_D47_T + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1056ppm_D47 + n_models_HadCM_new_1056ppm_monthly)) * std_post_HadCM_new_1056ppm_SAT_D47_T / np.sqrt(n_update_HadCM_new_1056ppm_D47 + n_models_HadCM_new_1056ppm_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SAT panel
axs[0, 4].set_title('HadCM (new) 1056 ppm pCO2')
axs[0, 4].set_xlabel('Month')
axs[0, 4].set_ylabel('Surface Air Temperature (°C)')
# axs[0, 4].legend(loc='upper left')
axs[0, 4].grid(True)
axs[0, 4].set_xticks(months_scale, month_names, rotation=45, ha="right")
# precip Results
# PRIOR
axs[1, 4].plot(months_scale, mu_prior_HadCM_new_1056ppm_precip_monthly, label='Prior Mean', color='b', marker='o')
axs[1, 4].fill_between(months_scale,
mu_prior_HadCM_new_1056ppm_precip_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_precip_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
mu_prior_HadCM_new_1056ppm_precip_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_new_1056ppm_monthly) * std_prior_HadCM_new_1056ppm_precip_monthly / np.sqrt(n_models_HadCM_new_1056ppm_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[1, 4].plot(months_scale, mu_post_HadCM_new_1056ppm_precip, label='Posterior Mean', color='r', marker='o')
axs[1, 4].fill_between(months_scale,
mu_post_HadCM_new_1056ppm_precip - stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1056ppm_d18Oc + n_models_HadCM_new_1056ppm_monthly)) * std_post_HadCM_new_1056ppm_precip / np.sqrt(n_update_HadCM_new_1056ppm_d18Oc + n_models_HadCM_new_1056ppm_monthly),
mu_post_HadCM_new_1056ppm_precip + stats.t.ppf(1 - 0.025, (n_update_HadCM_new_1056ppm_d18Oc + n_models_HadCM_new_1056ppm_monthly)) * std_post_HadCM_new_1056ppm_precip / np.sqrt(n_update_HadCM_new_1056ppm_d18Oc + n_models_HadCM_new_1056ppm_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for precip panel
# axs[1, 4].set_title('monthly Sea Surface Salinity (precip)')
axs[1, 4].set_xlabel('Month')
axs[1, 4].set_ylabel('Precipitation (mm/day)')
# axs[1, 4].legend(loc='upper left')
axs[1, 4].grid(True)
axs[1, 4].set_xticks(months_scale, month_names, rotation=45, ha="right")
# Next panels similar but for HadCM (old) with 2x preindustrial pCO2 forcing
# SAT Results
# PRIOR
axs[0, 5].plot(months_scale, mu_prior_HadCM_old_2PIC_SAT_monthly, label='Prior Mean', color='b', marker='o')
axs[0, 5].fill_between(months_scale,
mu_prior_HadCM_old_2PIC_SAT_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SAT_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
mu_prior_HadCM_old_2PIC_SAT_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_SAT_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[0, 5].plot(months_scale, mu_likelihood_T, label='Likelihood Mean', color='y', marker='o')
axs[0, 5].fill_between(months_scale,
mu_likelihood_T - stats.t.ppf(1 - 0.025, n_update_HadCM_old_2PIC_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_old_2PIC_D47),
mu_likelihood_T + stats.t.ppf(1 - 0.025, n_update_HadCM_old_2PIC_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_old_2PIC_D47),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[0, 5].plot(months_scale, mu_post_HadCM_old_2PIC_SAT_D47_T, label='Posterior Mean', color='r', marker='o')
axs[0, 5].fill_between(months_scale,
mu_post_HadCM_old_2PIC_SAT_D47_T - stats.t.ppf(1 - 0.025, (n_update_HadCM_old_2PIC_D47 + n_models_HadCM_old_2PIC_monthly)) * std_post_HadCM_old_2PIC_SAT_D47_T / np.sqrt(n_update_HadCM_old_2PIC_D47 + n_models_HadCM_old_2PIC_monthly),
mu_post_HadCM_old_2PIC_SAT_D47_T + stats.t.ppf(1 - 0.025, (n_update_HadCM_old_2PIC_D47 + n_models_HadCM_old_2PIC_monthly)) * std_post_HadCM_old_2PIC_SAT_D47_T / np.sqrt(n_update_HadCM_old_2PIC_D47 + n_models_HadCM_old_2PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SAT panel
axs[0, 5].set_title('HadCM (old) 2x preindustrial pCO2')
axs[0, 5].set_xlabel('Month')
axs[0, 5].set_ylabel('Surface Air Temperature (°C)')
# axs[0, 5].legend(loc='upper left')
axs[0, 5].grid(True)
axs[0, 5].set_xticks(months_scale, month_names, rotation=45, ha="right")
# precip Results
# PRIOR
axs[1, 5].plot(months_scale, mu_prior_HadCM_old_2PIC_precip_monthly, label='Prior Mean', color='b', marker='o')
axs[1, 5].fill_between(months_scale,
mu_prior_HadCM_old_2PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_precip_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
mu_prior_HadCM_old_2PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_2PIC_monthly) * std_prior_HadCM_old_2PIC_precip_monthly / np.sqrt(n_models_HadCM_old_2PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[1, 5].plot(months_scale, mu_post_HadCM_old_2PIC_precip, label='Posterior Mean', color='r', marker='o')
axs[1, 5].fill_between(months_scale,
mu_post_HadCM_old_2PIC_precip - stats.t.ppf(1 - 0.025, (n_update_HadCM_old_2PIC_d18Oc + n_models_HadCM_old_2PIC_monthly)) * std_post_HadCM_old_2PIC_precip / np.sqrt(n_update_HadCM_old_2PIC_d18Oc + n_models_HadCM_old_2PIC_monthly),
mu_post_HadCM_old_2PIC_precip + stats.t.ppf(1 - 0.025, (n_update_HadCM_old_2PIC_d18Oc + n_models_HadCM_old_2PIC_monthly)) * std_post_HadCM_old_2PIC_precip / np.sqrt(n_update_HadCM_old_2PIC_d18Oc + n_models_HadCM_old_2PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for precip panel
# axs[1, 5].set_title('monthly Sea Surface Salinity (precip)')
axs[1, 5].set_xlabel('Month')
axs[1, 5].set_ylabel('Precipitation (mm/day)')
# axs[1, 5].legend(loc='upper left')
axs[1, 5].grid(True)
axs[1, 5].set_xticks(months_scale, month_names, rotation=45, ha="right")
# Next panels similar but for HadCM (old) with 2x preindustrial pCO2 forcing
# SAT Results
# PRIOR
axs[0, 6].plot(months_scale, mu_prior_HadCM_old_4PIC_SAT_monthly, label='Prior Mean', color='b', marker='o')
axs[0, 6].fill_between(months_scale,
mu_prior_HadCM_old_4PIC_SAT_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SAT_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
mu_prior_HadCM_old_4PIC_SAT_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_SAT_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# LIKELIHOOD
axs[0, 6].plot(months_scale, mu_likelihood_T, label='Likelihood Mean', color='y', marker='o')
axs[0, 6].fill_between(months_scale,
mu_likelihood_T - stats.t.ppf(1 - 0.025, n_update_HadCM_old_4PIC_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_old_4PIC_D47),
mu_likelihood_T + stats.t.ppf(1 - 0.025, n_update_HadCM_old_4PIC_D47) * std_likelihood_T / np.sqrt(n_update_HadCM_old_4PIC_D47),
color='y', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[0, 6].plot(months_scale, mu_post_HadCM_old_4PIC_SAT_D47_T, label='Posterior Mean', color='r', marker='o')
axs[0, 6].fill_between(months_scale,
mu_post_HadCM_old_4PIC_SAT_D47_T - stats.t.ppf(1 - 0.025, (n_update_HadCM_old_4PIC_D47 + n_models_HadCM_old_4PIC_monthly)) * std_post_HadCM_old_4PIC_SAT_D47_T / np.sqrt(n_update_HadCM_old_4PIC_D47 + n_models_HadCM_old_4PIC_monthly),
mu_post_HadCM_old_4PIC_SAT_D47_T + stats.t.ppf(1 - 0.025, (n_update_HadCM_old_4PIC_D47 + n_models_HadCM_old_4PIC_monthly)) * std_post_HadCM_old_4PIC_SAT_D47_T / np.sqrt(n_update_HadCM_old_4PIC_D47 + n_models_HadCM_old_4PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for SAT panel
axs[0, 6].set_title('HadCM (old) 4x preindustrial pCO2')
axs[0, 6].set_xlabel('Month')
axs[0, 6].set_ylabel('Surface Air Temperature (°C)')
axs[0, 6].legend(loc='upper left')
axs[0, 6].grid(True)
axs[0, 6].set_xticks(months_scale, month_names, rotation=45, ha="right")
# precip Results
# PRIOR
axs[1, 6].plot(months_scale, mu_prior_HadCM_old_4PIC_precip_monthly, label='Prior Mean', color='b', marker='o')
axs[1, 6].fill_between(months_scale,
mu_prior_HadCM_old_4PIC_precip_monthly - stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_precip_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
mu_prior_HadCM_old_4PIC_precip_monthly + stats.t.ppf(1 - 0.025, n_models_HadCM_old_4PIC_monthly) * std_prior_HadCM_old_4PIC_precip_monthly / np.sqrt(n_models_HadCM_old_4PIC_monthly),
color='b', alpha=0.2, label='95% Confidence Interval')
# POSTERIOR
axs[1, 6].plot(months_scale, mu_post_HadCM_old_4PIC_precip, label='Posterior Mean', color='r', marker='o')
axs[1, 6].fill_between(months_scale,
mu_post_HadCM_old_4PIC_precip - stats.t.ppf(1 - 0.025, (n_update_HadCM_old_4PIC_d18Oc + n_models_HadCM_old_4PIC_monthly)) * std_post_HadCM_old_4PIC_precip / np.sqrt(n_update_HadCM_old_4PIC_d18Oc + n_models_HadCM_old_4PIC_monthly),
mu_post_HadCM_old_4PIC_precip + stats.t.ppf(1 - 0.025, (n_update_HadCM_old_4PIC_d18Oc + n_models_HadCM_old_4PIC_monthly)) * std_post_HadCM_old_4PIC_precip / np.sqrt(n_update_HadCM_old_4PIC_d18Oc + n_models_HadCM_old_4PIC_monthly),
color='r', alpha=0.2, label='95% Confidence Interval')
# Layout for precip panel
# axs[1, 6].set_title('monthly Sea Surface Salinity (precip)')
axs[1, 6].set_xlabel('Month')
axs[1, 6].set_ylabel('Precipitation (mm/day)')
axs[1, 6].legend(loc='upper left')
axs[1, 6].grid(True)
axs[1, 6].set_xticks(months_scale, month_names, rotation=45, ha="right")
# Shared x-axis labels
plt.xticks(months_scale, month_names, rotation=45, ha="right")
plt.suptitle('Seasonal Surface Air Temperature (SAT) and precipitation outcomes for all model scenarios', fontsize=16)
plt.tight_layout()
plt.show()
Final plot for pCO2 and inter-model comparison¶
Aggregate statistics on posterior outcomes on SST and SAT for all cases¶
In [80]:
# Prepare the data for the table
data = {
"Data Type": [
"Prior CESM 2PIC",
"Prior CESM 4PIC",
"Prior HadCM (new) 1PIC",
"Prior HadCM (new) 2PIC",
"Prior HadCM (new) 1056ppm",
"Prior HadCM (old) 2PIC",
"Prior HadCM (old) 4PIC",
"Likelihood Measurements",
"Posterior CESM 2PIC",
"Posterior CESM 4PIC",
"Posterior HadCM (new) 1PIC",
"Posterior HadCM (new) 2PIC",
"Posterior HadCM (new) 1056ppm",
"Posterior HadCM (old) 2PIC",
"Posterior HadCM (old) 4PIC"
]
}
# Add monthly means and standard deviations to the data dictionary
months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
# Process and rename the means and standard deviations for each data source
SST_means_prior_CESM_2PIC = D47c.OGLS23.T47(D47 = mu_prior_CESM_2PIC_SST_D47_monthly_original, sD47 = cov_prior_CESM_2PIC_SST_D47_monthly_original, return_covar = True)[0]
SST_stds_prior_CESM_2PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_prior_CESM_2PIC_SST_D47_monthly_original, sD47 = cov_prior_CESM_2PIC_SST_D47_monthly_original, return_covar = True)[1]))
SST_means_prior_CESM_4PIC = D47c.OGLS23.T47(D47 = mu_prior_CESM_4PIC_SST_D47_monthly_original, sD47 = cov_prior_CESM_4PIC_SST_D47_monthly_original, return_covar = True)[0]
SST_stds_prior_CESM_4PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_prior_CESM_4PIC_SST_D47_monthly_original, sD47 = cov_prior_CESM_4PIC_SST_D47_monthly_original, return_covar = True)[1]))
SST_means_prior_HadCM_new_1PIC = D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_1PIC_SST_D47_monthly, sD47 = cov_prior_HadCM_new_1PIC_SST_D47_monthly, return_covar = True)[0]
SST_stds_prior_HadCM_new_1PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_1PIC_SST_D47_monthly, sD47 = cov_prior_HadCM_new_1PIC_SST_D47_monthly, return_covar = True)[1]))
SST_means_prior_HadCM_new_2PIC = D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_2PIC_SST_D47_monthly, sD47 = cov_prior_HadCM_new_2PIC_SST_D47_monthly, return_covar = True)[0]
SST_stds_prior_HadCM_new_2PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_2PIC_SST_D47_monthly, sD47 = cov_prior_HadCM_new_2PIC_SST_D47_monthly, return_covar = True)[1]))
SST_means_prior_HadCM_new_1056ppm = D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_1056ppm_SST_D47_monthly, sD47 = cov_prior_HadCM_new_1056ppm_SST_D47_monthly, return_covar = True)[0]
SST_stds_prior_HadCM_new_1056ppm = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_1056ppm_SST_D47_monthly, sD47 = cov_prior_HadCM_new_1056ppm_SST_D47_monthly, return_covar = True)[1]))
SST_means_prior_HadCM_old_2PIC = D47c.OGLS23.T47(D47 = mu_prior_HadCM_old_2PIC_SST_D47_monthly, sD47 = cov_prior_HadCM_old_2PIC_SST_D47_monthly, return_covar = True)[0]
SST_stds_prior_HadCM_old_2PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_prior_HadCM_old_2PIC_SST_D47_monthly, sD47 = cov_prior_HadCM_old_2PIC_SST_D47_monthly, return_covar = True)[1]))
SST_means_prior_HadCM_old_4PIC = D47c.OGLS23.T47(D47 = mu_prior_HadCM_old_4PIC_SST_D47_monthly, sD47 = cov_prior_HadCM_old_4PIC_SST_D47_monthly, return_covar = True)[0]
SST_stds_prior_HadCM_old_4PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_prior_HadCM_old_4PIC_SST_D47_monthly, sD47 = cov_prior_HadCM_old_4PIC_SST_D47_monthly, return_covar = True)[1]))
SST_likelihood_means = D47c.OGLS23.T47(D47 = mu_likelihood[var_start_D47_monthly:var_end_D47_monthly], sD47 = std_likelihood[var_start_D47_monthly:var_end_D47_monthly], return_covar = True)[0]
SST_likelihood_stds = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_likelihood[var_start_D47_monthly:var_end_D47_monthly], sD47 = std_likelihood[var_start_D47_monthly:var_end_D47_monthly], return_covar = True)[1]))
SST_means_post_CESM_2PIC = D47c.OGLS23.T47(D47 = mu_post_CESM_2PIC_SST_D47, sD47 = cov_post_CESM_2PIC_SST_D47, return_covar = True)[0]
SST_stds_post_CESM_2PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_post_CESM_2PIC_SST_D47, sD47 = cov_post_CESM_2PIC_SST_D47, return_covar = True)[1]))
SST_means_post_CESM_4PIC = D47c.OGLS23.T47(D47 = mu_post_CESM_4PIC_SST_D47, sD47 = cov_post_CESM_4PIC_SST_D47, return_covar = True)[0]
SST_stds_post_CESM_4PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_post_CESM_4PIC_SST_D47, sD47 = cov_post_CESM_4PIC_SST_D47, return_covar = True)[1]))
SST_means_post_HadCM_new_1PIC = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_1PIC_SST_D47, sD47 = cov_post_HadCM_new_1PIC_SST_D47, return_covar = True)[0]
SST_stds_post_HadCM_new_1PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_post_HadCM_new_1PIC_SST_D47, sD47 = cov_post_HadCM_new_1PIC_SST_D47, return_covar = True)[1]))
SST_means_post_HadCM_new_2PIC = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_2PIC_SST_D47, sD47 = cov_post_HadCM_new_2PIC_SST_D47, return_covar = True)[0]
SST_stds_post_HadCM_new_2PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_post_HadCM_new_2PIC_SST_D47, sD47 = cov_post_HadCM_new_2PIC_SST_D47, return_covar = True)[1]))
SST_means_post_HadCM_new_1056ppm = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_1056ppm_SST_D47, sD47 = cov_post_HadCM_new_1056ppm_SST_D47, return_covar = True)[0]
SST_stds_post_HadCM_new_1056ppm = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_post_HadCM_new_1056ppm_SST_D47, sD47 = cov_post_HadCM_new_1056ppm_SST_D47, return_covar = True)[1]))
SST_means_post_HadCM_old_2PIC = D47c.OGLS23.T47(D47 = mu_post_HadCM_old_2PIC_SST_D47, sD47 = cov_post_HadCM_old_2PIC_SST_D47, return_covar = True)[0]
SST_stds_post_HadCM_old_2PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_post_HadCM_old_2PIC_SST_D47, sD47 = cov_post_HadCM_old_2PIC_SST_D47, return_covar = True)[1]))
SST_means_post_HadCM_old_4PIC = D47c.OGLS23.T47(D47 = mu_post_HadCM_old_4PIC_SST_D47, sD47 = cov_post_HadCM_old_4PIC_SST_D47, return_covar = True)[0]
SST_stds_post_HadCM_old_4PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_post_HadCM_old_4PIC_SST_D47, sD47 = cov_post_HadCM_old_4PIC_SST_D47, return_covar = True)[1]))
# Process and rename the means and standard deviations for each data source
SAT_means_prior_CESM_2PIC = D47c.OGLS23.T47(D47 = mu_prior_CESM_2PIC_SAT_D47_monthly_original, sD47 = cov_prior_CESM_2PIC_SAT_D47_monthly_original, return_covar = True)[0]
SAT_stds_prior_CESM_2PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_prior_CESM_2PIC_SAT_D47_monthly_original, sD47 = cov_prior_CESM_2PIC_SAT_D47_monthly_original, return_covar = True)[1]))
SAT_means_prior_CESM_4PIC = D47c.OGLS23.T47(D47 = mu_prior_CESM_4PIC_SAT_D47_monthly_original, sD47 = cov_prior_CESM_4PIC_SAT_D47_monthly_original, return_covar = True)[0]
SAT_stds_prior_CESM_4PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_prior_CESM_4PIC_SAT_D47_monthly_original, sD47 = cov_prior_CESM_4PIC_SAT_D47_monthly_original, return_covar = True)[1]))
SAT_means_prior_HadCM_new_1PIC = D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_1PIC_SAT_D47_monthly, sD47 = cov_prior_HadCM_new_1PIC_SAT_D47_monthly, return_covar = True)[0]
SAT_stds_prior_HadCM_new_1PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_1PIC_SAT_D47_monthly, sD47 = cov_prior_HadCM_new_1PIC_SAT_D47_monthly, return_covar = True)[1]))
SAT_means_prior_HadCM_new_2PIC = D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_2PIC_SAT_D47_monthly, sD47 = cov_prior_HadCM_new_2PIC_SAT_D47_monthly, return_covar = True)[0]
SAT_stds_prior_HadCM_new_2PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_2PIC_SAT_D47_monthly, sD47 = cov_prior_HadCM_new_2PIC_SAT_D47_monthly, return_covar = True)[1]))
SAT_means_prior_HadCM_new_1056ppm = D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_1056ppm_SAT_D47_monthly, sD47 = cov_prior_HadCM_new_1056ppm_SAT_D47_monthly, return_covar = True)[0]
SAT_stds_prior_HadCM_new_1056ppm = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_prior_HadCM_new_1056ppm_SAT_D47_monthly, sD47 = cov_prior_HadCM_new_1056ppm_SAT_D47_monthly, return_covar = True)[1]))
SAT_means_prior_HadCM_old_2PIC = D47c.OGLS23.T47(D47 = mu_prior_HadCM_old_2PIC_SAT_D47_monthly, sD47 = cov_prior_HadCM_old_2PIC_SAT_D47_monthly, return_covar = True)[0]
SAT_stds_prior_HadCM_old_2PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_prior_HadCM_old_2PIC_SAT_D47_monthly, sD47 = cov_prior_HadCM_old_2PIC_SAT_D47_monthly, return_covar = True)[1]))
SAT_means_prior_HadCM_old_4PIC = D47c.OGLS23.T47(D47 = mu_prior_HadCM_old_4PIC_SAT_D47_monthly, sD47 = cov_prior_HadCM_old_4PIC_SAT_D47_monthly, return_covar = True)[0]
SAT_stds_prior_HadCM_old_4PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_prior_HadCM_old_4PIC_SAT_D47_monthly, sD47 = cov_prior_HadCM_old_4PIC_SAT_D47_monthly, return_covar = True)[1]))
SAT_likelihood_means = D47c.OGLS23.T47(D47 = mu_likelihood[var_start_D47_monthly:var_end_D47_monthly], sD47 = std_likelihood[var_start_D47_monthly:var_end_D47_monthly], return_covar = True)[0]
SAT_likelihood_stds = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_likelihood[var_start_D47_monthly:var_end_D47_monthly], sD47 = std_likelihood[var_start_D47_monthly:var_end_D47_monthly], return_covar = True)[1]))
SAT_means_post_CESM_2PIC = D47c.OGLS23.T47(D47 = mu_post_CESM_2PIC_SAT_D47, sD47 = cov_post_CESM_2PIC_SAT_D47, return_covar = True)[0]
SAT_stds_post_CESM_2PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_post_CESM_2PIC_SAT_D47, sD47 = cov_post_CESM_2PIC_SAT_D47, return_covar = True)[1]))
SAT_means_post_CESM_4PIC = D47c.OGLS23.T47(D47 = mu_post_CESM_4PIC_SAT_D47, sD47 = cov_post_CESM_4PIC_SAT_D47, return_covar = True)[0]
SAT_stds_post_CESM_4PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_post_CESM_4PIC_SAT_D47, sD47 = cov_post_CESM_4PIC_SAT_D47, return_covar = True)[1]))
SAT_means_post_HadCM_new_1PIC = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_1PIC_SAT_D47, sD47 = cov_post_HadCM_new_1PIC_SAT_D47, return_covar = True)[0]
SAT_stds_post_HadCM_new_1PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_post_HadCM_new_1PIC_SAT_D47, sD47 = cov_post_HadCM_new_1PIC_SAT_D47, return_covar = True)[1]))
SAT_means_post_HadCM_new_2PIC = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_2PIC_SAT_D47, sD47 = cov_post_HadCM_new_2PIC_SAT_D47, return_covar = True)[0]
SAT_stds_post_HadCM_new_2PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_post_HadCM_new_2PIC_SAT_D47, sD47 = cov_post_HadCM_new_2PIC_SAT_D47, return_covar = True)[1]))
SAT_means_post_HadCM_new_1056ppm = D47c.OGLS23.T47(D47 = mu_post_HadCM_new_1056ppm_SAT_D47, sD47 = cov_post_HadCM_new_1056ppm_SAT_D47, return_covar = True)[0]
SAT_stds_post_HadCM_new_1056ppm = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_post_HadCM_new_1056ppm_SAT_D47, sD47 = cov_post_HadCM_new_1056ppm_SAT_D47, return_covar = True)[1]))
SAT_means_post_HadCM_old_2PIC = D47c.OGLS23.T47(D47 = mu_post_HadCM_old_2PIC_SAT_D47, sD47 = cov_post_HadCM_old_2PIC_SAT_D47, return_covar = True)[0]
SAT_stds_post_HadCM_old_2PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_post_HadCM_old_2PIC_SAT_D47, sD47 = cov_post_HadCM_old_2PIC_SAT_D47, return_covar = True)[1]))
SAT_means_post_HadCM_old_4PIC = D47c.OGLS23.T47(D47 = mu_post_HadCM_old_4PIC_SAT_D47, sD47 = cov_post_HadCM_old_4PIC_SAT_D47, return_covar = True)[0]
SAT_stds_post_HadCM_old_4PIC = np.sqrt(np.diag(D47c.OGLS23.T47(D47 = mu_post_HadCM_old_4PIC_SAT_D47, sD47 = cov_post_HadCM_old_4PIC_SAT_D47, return_covar = True)[1]))
# Combine all means and standard deviations into the data structure
all_SST_means = [
SST_means_prior_CESM_2PIC,
SST_means_prior_CESM_4PIC,
SST_means_prior_HadCM_new_1PIC,
SST_means_prior_HadCM_new_2PIC,
SST_means_prior_HadCM_new_1056ppm,
SST_means_prior_HadCM_old_2PIC,
SST_means_prior_HadCM_old_4PIC,
SST_likelihood_means,
SST_means_post_CESM_2PIC,
SST_means_post_CESM_4PIC,
SST_means_post_HadCM_new_1PIC,
SST_means_post_HadCM_new_2PIC,
SST_means_post_HadCM_new_1056ppm,
SST_means_post_HadCM_old_2PIC,
SST_means_post_HadCM_old_4PIC
]
all_SST_stds = [
SST_stds_prior_CESM_2PIC,
SST_stds_prior_CESM_4PIC,
SST_stds_prior_HadCM_new_1PIC,
SST_stds_prior_HadCM_new_2PIC,
SST_stds_prior_HadCM_new_1056ppm,
SST_stds_prior_HadCM_old_2PIC,
SST_stds_prior_HadCM_old_4PIC,
SST_likelihood_stds,
SST_stds_post_CESM_2PIC,
SST_stds_post_CESM_4PIC,
SST_stds_post_HadCM_new_1PIC,
SST_stds_post_HadCM_new_2PIC,
SST_stds_post_HadCM_new_1056ppm,
SST_stds_post_HadCM_old_2PIC,
SST_stds_post_HadCM_old_4PIC
]
all_SAT_means = [
SAT_means_prior_CESM_2PIC,
SAT_means_prior_CESM_4PIC,
SAT_means_prior_HadCM_new_1PIC,
SAT_means_prior_HadCM_new_2PIC,
SAT_means_prior_HadCM_new_1056ppm,
SAT_means_prior_HadCM_old_2PIC,
SAT_means_prior_HadCM_old_4PIC,
SAT_likelihood_means,
SAT_means_post_CESM_2PIC,
SAT_means_post_CESM_4PIC,
SAT_means_post_HadCM_new_1PIC,
SAT_means_post_HadCM_new_2PIC,
SAT_means_post_HadCM_new_1056ppm,
SAT_means_post_HadCM_old_2PIC,
SAT_means_post_HadCM_old_4PIC
]
all_SAT_stds = [
SAT_stds_prior_CESM_2PIC,
SAT_stds_prior_CESM_4PIC,
SAT_stds_prior_HadCM_new_1PIC,
SAT_stds_prior_HadCM_new_2PIC,
SAT_stds_prior_HadCM_new_1056ppm,
SAT_stds_prior_HadCM_old_2PIC,
SAT_stds_prior_HadCM_old_4PIC,
SAT_likelihood_stds,
SAT_stds_post_CESM_2PIC,
SAT_stds_post_CESM_4PIC,
SAT_stds_post_HadCM_new_1PIC,
SAT_stds_post_HadCM_new_2PIC,
SAT_stds_post_HadCM_new_1056ppm,
SAT_stds_post_HadCM_old_2PIC,
SAT_stds_post_HadCM_old_4PIC
]
# Create a dictionary to store all the data
all_temperature_data = {"Data Type": data["Data Type"]}
# Add SST means and stds
for i, month in enumerate(months):
all_temperature_data[f"{month} SST Mean"] = [means[i] for means in all_SST_means]
all_temperature_data[f"{month} SST Std"] = [stds[i] for stds in all_SST_stds]
# Add SAT means and stds
for i, month in enumerate(months):
all_temperature_data[f"{month} SAT Mean"] = [means[i] for means in all_SAT_means]
all_temperature_data[f"{month} SAT Std"] = [stds[i] for stds in all_SAT_stds]
# Create the Pandas DataFrame
all_temperature_pCO2_test_table_df = pd.DataFrame(all_temperature_data)
# Set the 'Data Type' column as the index
all_temperature_pCO2_test_table_df = all_temperature_pCO2_test_table_df.set_index("Data Type")
# Export the table to a CSV file
all_temperature_pCO2_test_table_df.to_csv("Sensitivity_test_pCO2_models/all_temperature_pCO2_test_table.csv")
print("Combined data exported to Sensitivity_test_pCO2_models/all_temperature_pCO2_test_table.csv")
Combined data exported to Sensitivity_test_pCO2_models/all_temperature_pCO2_test_table.csv
Combined plot of measurements, priors and posteriors with precision uncertainties for temperature¶
In [81]:
fig, (ax1, ax3) = plt.subplots(
2, 1, figsize=(10, 8), sharex='col'
)
fig.subplots_adjust(hspace=0.1, wspace=0.25) # reduce vertical & horizontal spacing
# Define a colormap across all months
cmap = plt.cm.coolwarm
colors = [cmap(i / (len(months)-1)) for i in range(len(months))]
color_dict = dict(zip(months, colors))
# Define offsets for x-axis to avoid overlapping error bars
x_offsets = np.linspace(-0.3, 0.3, len(months))
# Define x values for each data type
x_values = np.arange(len(all_temperature_pCO2_test_table_df.index))
# --- SST plot ---
for month in months:
ax1.errorbar(
x = x_values + x_offsets[months.index(month)],
y = all_temperature_pCO2_test_table_df[f"{month} SST Mean"],
yerr = all_temperature_pCO2_test_table_df[f"{month} SST Std"],
capsize = 3,
fmt='.',
label=month,
color=color_dict[month]
)
# Add light green rectangle to highlight prior
ax1.add_patch(
Rectangle(
(-0.5, ax1.get_ylim()[0]), # (x,y)
7, # width
ax1.get_ylim()[1] - ax1.get_ylim()[0], # height
color='lightgreen',
alpha=0.3,
)
)
# Add light blue rectangle to highlight measurement
ax1.add_patch(
Rectangle(
(6.5, ax1.get_ylim()[0]), # (x,y)
1, # width
ax1.get_ylim()[1] - ax1.get_ylim()[0], # height
color='lightblue',
alpha=0.3,
)
)
# Add light red rectangle to highlight posteriors
ax1.add_patch(
Rectangle(
(7.5, ax1.get_ylim()[0]), # (x,y)
7, # width
ax1.get_ylim()[1] - ax1.get_ylim()[0], # height
color='red',
alpha=0.1,
)
)
ax1.set_xticks(x_values)
ax1.set_xticklabels(all_temperature_pCO2_test_table_df.index, rotation=45, ha="right")
# ax1.set_xlabel('test case')
ax1.set_ylabel('SST (degrees C)', color='purple')
ax1.tick_params(axis='y', labelcolor='purple')
# # Secondary axis for temperature
# ax1_temp = ax1.twinx()
# ax1_temp.set_ylabel('SST Temperature (°C)', color='purple')
# ax1_temp.tick_params(axis='y', labelcolor='purple')
# ax1_temp.set_yticks(
# ticks = D47c.OGLS23.T47(T = np.linspace(0, 50, 25))[0],
# labels = np.linspace(0, 50, 25).astype(int)
# )
# ax1_temp.set_ylim(ax1.get_ylim())
# --- SAT Plot ---
for month in months:
ax3.errorbar(
x = x_values + x_offsets[months.index(month)],
y = all_temperature_pCO2_test_table_df[f"{month} SAT Mean"],
yerr = all_temperature_pCO2_test_table_df[f"{month} SAT Std"],
capsize = 3,
fmt='.',
label=month,
color=color_dict[month]
)
# Add light green rectangle to highlight prior
ax3.add_patch(
Rectangle(
(-0.5, ax3.get_ylim()[0]), # (x,y)
7, # width
ax3.get_ylim()[1] - ax3.get_ylim()[0], # height
color='lightgreen',
alpha=0.3,
)
)
# Add light blue rectangle to highlight measurement
ax3.add_patch(
Rectangle(
(6.5, ax3.get_ylim()[0]), # (x,y)
1, # width
ax3.get_ylim()[1] - ax3.get_ylim()[0], # height
color='lightblue',
alpha=0.3,
)
)
# Add light red rectangle to highlight posteriors
ax3.add_patch(
Rectangle(
(7.5, ax3.get_ylim()[0]), # (x,y)
7, # width
ax3.get_ylim()[1] - ax3.get_ylim()[0], # height
color='red',
alpha=0.1,
)
)
ax3.set_xticks(x_values)
ax3.set_xticklabels(all_temperature_pCO2_test_table_df.index, rotation=45, ha="right")
ax3.set_ylabel('SAT (degrees C)', color='darkblue')
ax3.tick_params(axis='y', labelcolor='darkblue')
# # Secondary axis for temperature, based on d18Oc-temperature conversion used above
# ax3_temp = ax3.twinx()
# ax3_temp.set_ylabel('SAT Temperature (°C; assuming δ18Ow of 0‰)', color='darkblue')
# ax3_temp.tick_params(axis='y', labelcolor='darkblue')
# ax3_temp.set_yticks(
# ticks = ((20.6 - np.linspace(0, 50, 25)) / 4.34 - 0.27) + 0 + 0.27,
# labels = np.linspace(0, 50, 25).astype(int)
# )
# ax3_temp.set_ylim(ax3.get_ylim())
# ax3.set_title('SAT value by test case and Month')
# ---------------------------------------------------------
# Shared legend above all plots
handles1, labels1 = ax1.get_legend_handles_labels()
fig.legend(handles1, labels1,
loc="upper center",
bbox_to_anchor=(0.5, 0.95),
ncol=len(months) / 2,
frameon=False)
plt.tight_layout(rect=[0, 0, 1, 0.9]) # leave space for legend
plt.suptitle('Monthly Surface Temperature (SST and SAT) across all model scenarios', fontsize=16)
plt.show()